]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'staging/staging-next'
authorThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:59:28 +0000 (14:59 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:59:28 +0000 (14:59 +0200)
665 files changed:
Documentation/ABI/testing/sysfs-bus-iio
Documentation/devicetree/bindings/arm/atmel-adc.txt
Documentation/devicetree/bindings/iio/light/cm36651.txt [new file with mode: 0644]
Documentation/devicetree/bindings/iio/light/gp2ap020a00f.txt [new file with mode: 0644]
Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
Documentation/devicetree/bindings/vendor-prefixes.txt
MAINTAINERS
arch/arm/boot/dts/imx23.dtsi
arch/arm/boot/dts/imx28-evk.dts
arch/arm/boot/dts/imx28.dtsi
arch/arm/mach-at91/include/mach/at91_adc.h
drivers/hid/hid-sensor-hub.c
drivers/iio/accel/bma180.c
drivers/iio/accel/hid-sensor-accel-3d.c
drivers/iio/accel/st_accel_buffer.c
drivers/iio/accel/st_accel_core.c
drivers/iio/adc/Kconfig
drivers/iio/adc/Makefile
drivers/iio/adc/ad7266.c
drivers/iio/adc/ad7298.c
drivers/iio/adc/ad7476.c
drivers/iio/adc/ad7791.c
drivers/iio/adc/ad7887.c
drivers/iio/adc/ad7923.c
drivers/iio/adc/ad_sigma_delta.c
drivers/iio/adc/at91_adc.c
drivers/iio/adc/max1363.c
drivers/iio/adc/mcp3422.c [new file with mode: 0644]
drivers/iio/adc/nau7802.c
drivers/iio/adc/ti-adc081c.c
drivers/iio/adc/ti_am335x_adc.c
drivers/iio/buffer_cb.c
drivers/iio/common/hid-sensors/hid-sensor-trigger.c
drivers/iio/common/st_sensors/st_sensors_buffer.c
drivers/iio/common/st_sensors/st_sensors_core.c
drivers/iio/dac/Kconfig
drivers/iio/dac/ad5064.c
drivers/iio/dac/ad5360.c
drivers/iio/dac/ad5380.c
drivers/iio/dac/ad5421.c
drivers/iio/dac/ad5446.c
drivers/iio/dac/ad5449.c
drivers/iio/dac/ad5504.c
drivers/iio/dac/ad5624r_spi.c
drivers/iio/dac/ad5686.c
drivers/iio/dac/ad5755.c
drivers/iio/dac/ad5764.c
drivers/iio/dac/ad5791.c
drivers/iio/dac/ad7303.c
drivers/iio/dac/max517.c
drivers/iio/dac/mcp4725.c
drivers/iio/frequency/adf4350.c
drivers/iio/gyro/adis16080.c
drivers/iio/gyro/adis16130.c
drivers/iio/gyro/adis16260.c
drivers/iio/gyro/adxrs450.c
drivers/iio/gyro/hid-sensor-gyro-3d.c
drivers/iio/gyro/itg3200_buffer.c
drivers/iio/gyro/st_gyro_buffer.c
drivers/iio/gyro/st_gyro_core.c
drivers/iio/iio_core.h
drivers/iio/imu/adis16400_buffer.c
drivers/iio/imu/adis_buffer.c
drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
drivers/iio/industrialio-buffer.c
drivers/iio/industrialio-core.c
drivers/iio/industrialio-event.c
drivers/iio/industrialio-triggered-buffer.c
drivers/iio/kfifo_buf.c
drivers/iio/light/Kconfig
drivers/iio/light/Makefile
drivers/iio/light/adjd_s311.c
drivers/iio/light/apds9300.c
drivers/iio/light/cm36651.c [new file with mode: 0644]
drivers/iio/light/gp2ap020a00f.c [new file with mode: 0644]
drivers/iio/light/hid-sensor-als.c
drivers/iio/light/tcs3472.c [new file with mode: 0644]
drivers/iio/light/tsl2563.c
drivers/iio/light/tsl4531.c [new file with mode: 0644]
drivers/iio/magnetometer/hid-sensor-magn-3d.c
drivers/iio/magnetometer/st_magn_buffer.c
drivers/iio/magnetometer/st_magn_core.c
drivers/iio/pressure/st_pressure.h
drivers/iio/pressure/st_pressure_buffer.c
drivers/iio/pressure/st_pressure_core.c
drivers/iio/pressure/st_pressure_i2c.c
drivers/iio/temperature/tmp006.c
drivers/iio/trigger/iio-trig-sysfs.c
drivers/input/touchscreen/ti_am335x_tsc.c
drivers/rtc/rtc-hid-sensor-time.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/android/Kconfig
drivers/staging/android/alarm-dev.c
drivers/staging/android/ashmem.c
drivers/staging/android/binder.c
drivers/staging/android/timed_output.h
drivers/staging/bcm/Bcmnet.c
drivers/staging/bcm/InterfaceMisc.c
drivers/staging/bcm/PHSModule.c
drivers/staging/bcm/nvm.c
drivers/staging/btmtk_usb/btmtk_usb.c
drivers/staging/ced1401/ced_ioc.c
drivers/staging/comedi/Kconfig
drivers/staging/comedi/comedi_buf.c
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/comedidev.h
drivers/staging/comedi/drivers.c
drivers/staging/comedi/drivers/8253.h
drivers/staging/comedi/drivers/8255.c
drivers/staging/comedi/drivers/addi-data/addi_common.c
drivers/staging/comedi/drivers/addi-data/addi_common.h
drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
drivers/staging/comedi/drivers/addi_apci_1516.c
drivers/staging/comedi/drivers/addi_apci_16xx.c
drivers/staging/comedi/drivers/addi_apci_2032.c
drivers/staging/comedi/drivers/addi_apci_2200.c
drivers/staging/comedi/drivers/addi_apci_3120.c
drivers/staging/comedi/drivers/addi_apci_3501.c
drivers/staging/comedi/drivers/addi_apci_3xxx.c
drivers/staging/comedi/drivers/adl_pci6208.c
drivers/staging/comedi/drivers/adl_pci7x3x.c
drivers/staging/comedi/drivers/adl_pci9111.c
drivers/staging/comedi/drivers/adl_pci9118.c
drivers/staging/comedi/drivers/adq12b.c
drivers/staging/comedi/drivers/adv_pci1710.c
drivers/staging/comedi/drivers/adv_pci1723.c
drivers/staging/comedi/drivers/adv_pci_dio.c
drivers/staging/comedi/drivers/aio_iiro_16.c
drivers/staging/comedi/drivers/amplc_dio200_common.c
drivers/staging/comedi/drivers/amplc_pc263.c
drivers/staging/comedi/drivers/amplc_pci224.c
drivers/staging/comedi/drivers/amplc_pci230.c
drivers/staging/comedi/drivers/amplc_pci263.c
drivers/staging/comedi/drivers/cb_das16_cs.c
drivers/staging/comedi/drivers/cb_pcidas.c
drivers/staging/comedi/drivers/cb_pcidas64.c
drivers/staging/comedi/drivers/comedi_fc.h
drivers/staging/comedi/drivers/comedi_parport.c
drivers/staging/comedi/drivers/contec_pci_dio.c
drivers/staging/comedi/drivers/das08.c
drivers/staging/comedi/drivers/das08.h
drivers/staging/comedi/drivers/das16.c
drivers/staging/comedi/drivers/das16m1.c
drivers/staging/comedi/drivers/das1800.c
drivers/staging/comedi/drivers/das800.c
drivers/staging/comedi/drivers/dmm32at.c
drivers/staging/comedi/drivers/dt2801.c
drivers/staging/comedi/drivers/dt2811.c
drivers/staging/comedi/drivers/dt2817.c
drivers/staging/comedi/drivers/dt282x.c
drivers/staging/comedi/drivers/dt3000.c
drivers/staging/comedi/drivers/dt9812.c
drivers/staging/comedi/drivers/dyna_pci10xx.c
drivers/staging/comedi/drivers/fl512.c
drivers/staging/comedi/drivers/icp_multi.c
drivers/staging/comedi/drivers/ii_pci20kc.c
drivers/staging/comedi/drivers/me4000.c
drivers/staging/comedi/drivers/me_daq.c
drivers/staging/comedi/drivers/multiq3.c
drivers/staging/comedi/drivers/ni_6527.c
drivers/staging/comedi/drivers/ni_660x.c
drivers/staging/comedi/drivers/ni_670x.c
drivers/staging/comedi/drivers/ni_at_a2150.c
drivers/staging/comedi/drivers/ni_at_ao.c
drivers/staging/comedi/drivers/ni_atmio16d.c
drivers/staging/comedi/drivers/ni_daq_700.c
drivers/staging/comedi/drivers/ni_labpc.c
drivers/staging/comedi/drivers/ni_mio_common.c
drivers/staging/comedi/drivers/ni_pcidio.c
drivers/staging/comedi/drivers/ni_stc.h
drivers/staging/comedi/drivers/pcl711.c
drivers/staging/comedi/drivers/pcl726.c
drivers/staging/comedi/drivers/pcl730.c
drivers/staging/comedi/drivers/pcl812.c
drivers/staging/comedi/drivers/pcl816.c
drivers/staging/comedi/drivers/pcl818.c
drivers/staging/comedi/drivers/pcmad.c
drivers/staging/comedi/drivers/pcmmio.c
drivers/staging/comedi/drivers/pcmuio.c
drivers/staging/comedi/drivers/quatech_daqp_cs.c
drivers/staging/comedi/drivers/rtd520.c
drivers/staging/comedi/drivers/rti800.c
drivers/staging/comedi/drivers/s526.c
drivers/staging/comedi/drivers/s626.c
drivers/staging/comedi/drivers/s626.h
drivers/staging/comedi/drivers/skel.c
drivers/staging/comedi/drivers/ssv_dnp.c
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/comedi/drivers/usbduxsigma.c
drivers/staging/comedi/drivers/vmk80xx.c
drivers/staging/crystalhd/crystalhd_hw.c
drivers/staging/crystalhd/crystalhd_lnx.c
drivers/staging/cxt1e1/comet.c
drivers/staging/cxt1e1/comet.h
drivers/staging/cxt1e1/hwprobe.c
drivers/staging/cxt1e1/linux.c
drivers/staging/cxt1e1/musycc.c
drivers/staging/cxt1e1/pmcc4_drv.c
drivers/staging/cxt1e1/sbecom_inline_linux.h
drivers/staging/cxt1e1/sbecrc.c
drivers/staging/cxt1e1/sbeid.c
drivers/staging/cxt1e1/sbeproc.c
drivers/staging/cxt1e1/sbew_ioc.h
drivers/staging/dgap/Makefile
drivers/staging/dgap/dgap_downld.h
drivers/staging/dgap/dgap_driver.c
drivers/staging/dgap/dgap_driver.h
drivers/staging/dgap/dgap_fep5.c
drivers/staging/dgap/dgap_fep5.h
drivers/staging/dgap/dgap_kcompat.h
drivers/staging/dgap/dgap_parse.c
drivers/staging/dgap/dgap_sysfs.c
drivers/staging/dgap/dgap_tty.c
drivers/staging/dgap/digi.h
drivers/staging/dgap/downld.c
drivers/staging/dgnc/dgnc_cls.c
drivers/staging/dgnc/dgnc_driver.c
drivers/staging/dgnc/dgnc_driver.h
drivers/staging/dgnc/dgnc_kcompat.h
drivers/staging/dgnc/dgnc_mgmt.c
drivers/staging/dgnc/dgnc_neo.c
drivers/staging/dgnc/dgnc_neo.h
drivers/staging/dgnc/dgnc_sysfs.c
drivers/staging/dgnc/dgnc_sysfs.h
drivers/staging/dgnc/dgnc_tty.c
drivers/staging/dgnc/dgnc_tty.h
drivers/staging/dgnc/digi.h
drivers/staging/dgrp/dgrp_sysfs.c
drivers/staging/dwc2/TODO [new file with mode: 0644]
drivers/staging/dwc2/core.c
drivers/staging/dwc2/core.h
drivers/staging/dwc2/hcd.c
drivers/staging/dwc2/hcd.h
drivers/staging/dwc2/hcd_ddma.c
drivers/staging/dwc2/hcd_intr.c
drivers/staging/dwc2/hcd_queue.c
drivers/staging/dwc2/pci.c
drivers/staging/et131x/Module.symvers [new file with mode: 0644]
drivers/staging/et131x/README
drivers/staging/et131x/et131x.c
drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c
drivers/staging/ft1000/ft1000-usb/ft1000_download.c
drivers/staging/fwserial/fwserial.c
drivers/staging/gdm724x/gdm_lte.c
drivers/staging/gdm724x/gdm_mux.c
drivers/staging/gdm724x/gdm_tty.c
drivers/staging/iio/Documentation/iio_utils.h
drivers/staging/iio/TODO
drivers/staging/iio/accel/adis16220_core.c
drivers/staging/iio/accel/lis3l02dq_core.c
drivers/staging/iio/accel/lis3l02dq_ring.c
drivers/staging/iio/accel/sca3000_core.c
drivers/staging/iio/accel/sca3000_ring.c
drivers/staging/iio/adc/Kconfig
drivers/staging/iio/adc/ad7192.c
drivers/staging/iio/adc/ad7280a.c
drivers/staging/iio/adc/ad7291.c
drivers/staging/iio/adc/ad7606_core.c
drivers/staging/iio/adc/ad7606_ring.c
drivers/staging/iio/adc/ad7780.c
drivers/staging/iio/adc/ad7816.c
drivers/staging/iio/adc/ad799x.h
drivers/staging/iio/adc/ad799x_core.c
drivers/staging/iio/adc/ad799x_ring.c
drivers/staging/iio/adc/lpc32xx_adc.c
drivers/staging/iio/adc/mxs-lradc.c
drivers/staging/iio/adc/spear_adc.c
drivers/staging/iio/addac/adt7316-i2c.c
drivers/staging/iio/addac/adt7316-spi.c
drivers/staging/iio/addac/adt7316.c
drivers/staging/iio/cdc/ad7150.c
drivers/staging/iio/cdc/ad7746.c
drivers/staging/iio/frequency/ad5930.c
drivers/staging/iio/frequency/ad9832.c
drivers/staging/iio/frequency/ad9834.c
drivers/staging/iio/frequency/ad9850.c
drivers/staging/iio/frequency/ad9852.c
drivers/staging/iio/frequency/ad9910.c
drivers/staging/iio/frequency/ad9951.c
drivers/staging/iio/iio_simple_dummy.c
drivers/staging/iio/iio_simple_dummy.h
drivers/staging/iio/iio_simple_dummy_buffer.c
drivers/staging/iio/iio_simple_dummy_events.c
drivers/staging/iio/impedance-analyzer/ad5933.c
drivers/staging/iio/light/isl29018.c
drivers/staging/iio/light/tsl2583.c
drivers/staging/iio/light/tsl2x7x_core.c
drivers/staging/iio/magnetometer/hmc5843.c
drivers/staging/iio/meter/ade7753.c
drivers/staging/iio/meter/ade7754.c
drivers/staging/iio/meter/ade7758_core.c
drivers/staging/iio/meter/ade7758_ring.c
drivers/staging/iio/meter/ade7759.c
drivers/staging/iio/meter/ade7854-i2c.c
drivers/staging/iio/meter/ade7854-spi.c
drivers/staging/iio/meter/ade7854.c
drivers/staging/iio/resolver/ad2s1200.c
drivers/staging/iio/resolver/ad2s1210.c
drivers/staging/iio/resolver/ad2s90.c
drivers/staging/iio/trigger/iio-trig-bfin-timer.c
drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
drivers/staging/imx-drm/Makefile
drivers/staging/imx-drm/TODO
drivers/staging/imx-drm/imx-drm-core.c
drivers/staging/imx-drm/imx-drm.h
drivers/staging/imx-drm/imx-ldb.c
drivers/staging/imx-drm/imx-tve.c
drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h
drivers/staging/imx-drm/ipu-v3/ipu-common.c
drivers/staging/imx-drm/ipu-v3/ipu-dc.c
drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c
drivers/staging/imx-drm/ipuv3-crtc.c
drivers/staging/imx-drm/ipuv3-plane.c [new file with mode: 0644]
drivers/staging/imx-drm/ipuv3-plane.h [new file with mode: 0644]
drivers/staging/keucr/usb.c
drivers/staging/ktap/Kconfig [new file with mode: 0644]
drivers/staging/ktap/Makefile [new file with mode: 0644]
drivers/staging/ktap/README.md [new file with mode: 0644]
drivers/staging/ktap/doc/tutorial.md [new file with mode: 0644]
drivers/staging/ktap/include/ktap.h [new file with mode: 0644]
drivers/staging/ktap/include/ktap_opcodes.h [new file with mode: 0644]
drivers/staging/ktap/include/ktap_types.h [new file with mode: 0644]
drivers/staging/ktap/interpreter/ktap.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/library/ansilib.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/library/baselib.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/library/kdebug.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/library/timer.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/loader.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/object.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/opcode.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/strfmt.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/table.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/transport.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/tstring.c [new file with mode: 0644]
drivers/staging/ktap/interpreter/vm.c [new file with mode: 0644]
drivers/staging/ktap/scripts/basic/backtrace.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/basic/event_trigger.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/basic/event_trigger_ftrace.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/basic/ftrace.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/basic/function_time.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/basic/kretprobe.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/game/tetris.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/helloworld.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/interrupt/hardirq_time.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/interrupt/softirq_time.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/io/kprobes-do-sys-open.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/io/traceio.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/mem/kmalloc-top.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/mem/kmem.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/profiling/function_profiler.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/profiling/stack_profile.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/schedule/sched_transition.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/schedule/schedtimes.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/syscalls/errinfo.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/syscalls/sctop.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/syscalls/syscalls.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/syscalls/syscalls_count.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/syscalls/syscalls_count_by_proc.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/tracepoints/eventcount.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/tracepoints/eventcount_by_proc.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/tracepoints/tracepoints.kp [new file with mode: 0644]
drivers/staging/ktap/scripts/userspace/uprobes-malloc.kp [new file with mode: 0644]
drivers/staging/ktap/test/aggr_table.kp [new file with mode: 0644]
drivers/staging/ktap/test/ansi.kp [new file with mode: 0644]
drivers/staging/ktap/test/arg.kp [new file with mode: 0644]
drivers/staging/ktap/test/arith.kp [new file with mode: 0644]
drivers/staging/ktap/test/bench/sembench.c [new file with mode: 0644]
drivers/staging/ktap/test/bench/test.sh [new file with mode: 0644]
drivers/staging/ktap/test/concat.kp [new file with mode: 0644]
drivers/staging/ktap/test/count.kp [new file with mode: 0644]
drivers/staging/ktap/test/fibonacci.kp [new file with mode: 0644]
drivers/staging/ktap/test/function.kp [new file with mode: 0644]
drivers/staging/ktap/test/if.kp [new file with mode: 0644]
drivers/staging/ktap/test/kprobe.kp [new file with mode: 0644]
drivers/staging/ktap/test/kretprobe.kp [new file with mode: 0644]
drivers/staging/ktap/test/len.kp [new file with mode: 0644]
drivers/staging/ktap/test/looping.kp [new file with mode: 0644]
drivers/staging/ktap/test/pairs.kp [new file with mode: 0644]
drivers/staging/ktap/test/run_test.sh [new file with mode: 0644]
drivers/staging/ktap/test/table.kp [new file with mode: 0644]
drivers/staging/ktap/test/timer.kp [new file with mode: 0644]
drivers/staging/ktap/test/tracepoint.kp [new file with mode: 0644]
drivers/staging/ktap/test/zerodivide.kp [new file with mode: 0644]
drivers/staging/ktap/userspace/code.c [new file with mode: 0644]
drivers/staging/ktap/userspace/dump.c [new file with mode: 0644]
drivers/staging/ktap/userspace/eventdef.c [new file with mode: 0644]
drivers/staging/ktap/userspace/ktapc.h [new file with mode: 0644]
drivers/staging/ktap/userspace/ktapio.c [new file with mode: 0644]
drivers/staging/ktap/userspace/lex.c [new file with mode: 0644]
drivers/staging/ktap/userspace/main.c [new file with mode: 0644]
drivers/staging/ktap/userspace/parser.c [new file with mode: 0644]
drivers/staging/ktap/userspace/util.c [new file with mode: 0644]
drivers/staging/line6/driver.c
drivers/staging/line6/midi.c
drivers/staging/lustre/include/linux/libcfs/bitmap.h
drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h
drivers/staging/lustre/lnet/lnet/lib-move.c
drivers/staging/lustre/lnet/lnet/lo.c
drivers/staging/lustre/lnet/lnet/module.c
drivers/staging/lustre/lnet/lnet/router_proc.c
drivers/staging/lustre/lnet/selftest/brw_test.c
drivers/staging/lustre/lnet/selftest/conrpc.c
drivers/staging/lustre/lnet/selftest/console.c
drivers/staging/lustre/lnet/selftest/timer.c
drivers/staging/lustre/lustre/Kconfig
drivers/staging/lustre/lustre/fld/fld_cache.c
drivers/staging/lustre/lustre/include/cl_object.h
drivers/staging/lustre/lustre/include/lclient.h
drivers/staging/lustre/lustre/include/linux/lustre_compat25.h
drivers/staging/lustre/lustre/include/lustre/lustre_idl.h
drivers/staging/lustre/lustre/include/lustre_fid.h
drivers/staging/lustre/lustre/include/obd.h
drivers/staging/lustre/lustre/include/obd_support.h
drivers/staging/lustre/lustre/lclient/lcommon_cl.c
drivers/staging/lustre/lustre/ldlm/ldlm_lock.c
drivers/staging/lustre/lustre/ldlm/ldlm_resource.c
drivers/staging/lustre/lustre/libcfs/hash.c
drivers/staging/lustre/lustre/libcfs/linux/linux-curproc.c
drivers/staging/lustre/lustre/libcfs/linux/linux-debug.c
drivers/staging/lustre/lustre/libcfs/prng.c
drivers/staging/lustre/lustre/llite/dir.c
drivers/staging/lustre/lustre/llite/file.c
drivers/staging/lustre/lustre/llite/llite_close.c
drivers/staging/lustre/lustre/llite/llite_lib.c
drivers/staging/lustre/lustre/llite/lloop.c
drivers/staging/lustre/lustre/llite/rw.c
drivers/staging/lustre/lustre/llite/rw26.c
drivers/staging/lustre/lustre/llite/statahead.c
drivers/staging/lustre/lustre/lov/lov_cl_internal.h
drivers/staging/lustre/lustre/lov/lov_dev.c
drivers/staging/lustre/lustre/lov/lov_internal.h
drivers/staging/lustre/lustre/lov/lov_io.c
drivers/staging/lustre/lustre/lov/lov_lock.c
drivers/staging/lustre/lustre/lov/lov_obd.c
drivers/staging/lustre/lustre/lov/lov_object.c
drivers/staging/lustre/lustre/lov/lov_pack.c
drivers/staging/lustre/lustre/lov/lov_request.c
drivers/staging/lustre/lustre/lvfs/fsfilt.c
drivers/staging/lustre/lustre/lvfs/lvfs_lib.c
drivers/staging/lustre/lustre/lvfs/lvfs_linux.c
drivers/staging/lustre/lustre/obdclass/cl_io.c
drivers/staging/lustre/lustre/obdclass/class_obd.c
drivers/staging/lustre/lustre/obdclass/llog_test.c
drivers/staging/lustre/lustre/obdclass/lu_object.c
drivers/staging/lustre/lustre/obdclass/obd_config.c
drivers/staging/lustre/lustre/obdclass/uuid.c
drivers/staging/lustre/lustre/obdecho/echo_client.c
drivers/staging/lustre/lustre/osc/osc_lock.c
drivers/staging/lustre/lustre/osc/osc_page.c
drivers/staging/lustre/lustre/osc/osc_request.c
drivers/staging/lustre/lustre/ptlrpc/client.c
drivers/staging/lustre/lustre/ptlrpc/import.c
drivers/staging/lustre/lustre/ptlrpc/layout.c
drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c
drivers/staging/lustre/lustre/ptlrpc/service.c
drivers/staging/media/go7007/go7007-usb.c
drivers/staging/media/lirc/lirc_bt829.c
drivers/staging/mt29f_spinand/Kconfig [new file with mode: 0644]
drivers/staging/mt29f_spinand/Makefile [new file with mode: 0644]
drivers/staging/mt29f_spinand/TODO [new file with mode: 0644]
drivers/staging/mt29f_spinand/mt29f_spinand.c [new file with mode: 0644]
drivers/staging/mt29f_spinand/mt29f_spinand.h [new file with mode: 0644]
drivers/staging/netlogic/xlr_net.c
drivers/staging/netlogic/xlr_net.h
drivers/staging/nvec/nvec.c
drivers/staging/octeon-usb/Makefile
drivers/staging/octeon-usb/cvmx-usb.c [deleted file]
drivers/staging/octeon-usb/cvmx-usb.h [deleted file]
drivers/staging/octeon-usb/cvmx-usbnx-defs.h [deleted file]
drivers/staging/octeon-usb/octeon-hcd.c
drivers/staging/octeon-usb/octeon-hcd.h [moved from drivers/staging/octeon-usb/cvmx-usbcx-defs.h with 83% similarity]
drivers/staging/octeon/ethernet-rx.c
drivers/staging/octeon/ethernet-spi.c
drivers/staging/octeon/ethernet-tx.c
drivers/staging/octeon/ethernet.c
drivers/staging/olpc_dcon/Kconfig
drivers/staging/olpc_dcon/olpc_dcon.c
drivers/staging/quickstart/quickstart.c
drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
drivers/staging/rtl8187se/r8180_core.c
drivers/staging/rtl8187se/r8180_dm.c
drivers/staging/rtl8187se/r8180_rtl8225z2.c
drivers/staging/rtl8187se/r8180_wx.c
drivers/staging/rtl8187se/r8185b_init.c
drivers/staging/rtl8188eu/Makefile
drivers/staging/rtl8188eu/TODO
drivers/staging/rtl8188eu/core/rtw_ap.c
drivers/staging/rtl8188eu/core/rtw_br_ext.c
drivers/staging/rtl8188eu/core/rtw_cmd.c
drivers/staging/rtl8188eu/core/rtw_efuse.c
drivers/staging/rtl8188eu/core/rtw_ieee80211.c
drivers/staging/rtl8188eu/core/rtw_mlme.c
drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
drivers/staging/rtl8188eu/core/rtw_recv.c
drivers/staging/rtl8188eu/core/rtw_security.c
drivers/staging/rtl8188eu/core/rtw_sta_mgt.c
drivers/staging/rtl8188eu/core/rtw_wlan_util.c
drivers/staging/rtl8188eu/core/rtw_xmit.c
drivers/staging/rtl8188eu/hal/Hal8188EFWImg_CE.c [deleted file]
drivers/staging/rtl8188eu/hal/HalPhyRf_8188e.c
drivers/staging/rtl8188eu/hal/HalPwrSeqCmd.c
drivers/staging/rtl8188eu/hal/rtl8188e_cmd.c
drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c
drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c
drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c
drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
drivers/staging/rtl8188eu/hal/usb_halinit.c
drivers/staging/rtl8188eu/hal/usb_ops_linux.c
drivers/staging/rtl8188eu/include/Hal8188EFWImg_CE.h [deleted file]
drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h
drivers/staging/rtl8188eu/include/Hal8188EPhyReg.h
drivers/staging/rtl8188eu/include/HalPhyRf_8188e.h
drivers/staging/rtl8188eu/include/odm.h
drivers/staging/rtl8188eu/include/odm_HWConfig.h
drivers/staging/rtl8188eu/include/odm_debug.h
drivers/staging/rtl8188eu/include/odm_precomp.h
drivers/staging/rtl8188eu/include/rtw_cmd.h
drivers/staging/rtl8188eu/include/rtw_led.h
drivers/staging/rtl8188eu/include/rtw_mlme.h
drivers/staging/rtl8188eu/include/rtw_mlme_ext.h
drivers/staging/rtl8188eu/include/rtw_mp_phy_regdef.h
drivers/staging/rtl8188eu/include/rtw_recv.h
drivers/staging/rtl8188eu/include/rtw_rf.h
drivers/staging/rtl8188eu/include/sta_info.h
drivers/staging/rtl8188eu/include/wifi.h
drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
drivers/staging/rtl8188eu/os_dep/os_intfs.c
drivers/staging/rtl8188eu/os_dep/osdep_service.c
drivers/staging/rtl8188eu/os_dep/recv_linux.c
drivers/staging/rtl8188eu/os_dep/usb_intf.c
drivers/staging/rtl8192e/dot11d.c
drivers/staging/rtl8192e/dot11d.h
drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
drivers/staging/rtl8192e/rtl8192e/rtl_core.c
drivers/staging/rtl8192e/rtllib_rx.c
drivers/staging/rtl8192u/dot11d.h [deleted file]
drivers/staging/rtl8192u/ieee80211/dot11d.h
drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c
drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c
drivers/staging/rtl8192u/ieee80211/rtl819x_BAProc.c
drivers/staging/rtl8192u/ieee80211_crypt.h [deleted file]
drivers/staging/rtl8192u/r8180_pm.c [deleted file]
drivers/staging/rtl8192u/r8180_pm.h [deleted file]
drivers/staging/rtl8192u/r8190_rtl8256.h
drivers/staging/rtl8192u/r8192U.h
drivers/staging/rtl8192u/r8192U_core.c
drivers/staging/rtl8192u/r8192U_dm.c
drivers/staging/rtl8192u/r8192U_wx.c
drivers/staging/rtl8192u/r819xU_HTType.h
drivers/staging/rtl8192u/r819xU_cmdpkt.c
drivers/staging/rtl8192u/r819xU_cmdpkt.h
drivers/staging/rtl8192u/r819xU_firmware.c
drivers/staging/rtl8192u/r819xU_phy.c
drivers/staging/rtl8192u/r819xU_phy.h
drivers/staging/rtl8712/os_intfs.c
drivers/staging/rtl8712/rtl8712_cmd.c
drivers/staging/rtl8712/rtl8712_efuse.c
drivers/staging/rtl8712/rtl8712_recv.c
drivers/staging/rtl8712/rtl871x_cmd.c
drivers/staging/rtl8712/rtl871x_ioctl_linux.c
drivers/staging/rtl8712/rtl871x_ioctl_rtl.c
drivers/staging/rtl8712/rtl871x_mlme.c
drivers/staging/rtl8712/rtl871x_mp.c
drivers/staging/rtl8712/rtl871x_security.c
drivers/staging/rtl8712/rtl871x_sta_mgt.c
drivers/staging/rtl8712/usb_intf.c
drivers/staging/rtl8712/xmit_linux.c
drivers/staging/sb105x/sb_mp_register.h
drivers/staging/sb105x/sb_pci_mp.c
drivers/staging/sep/sep_crypto.c
drivers/staging/sep/sep_main.c
drivers/staging/silicom/bp_mod.h
drivers/staging/silicom/bpctl_mod.c
drivers/staging/slicoss/slicoss.c
drivers/staging/sm7xxfb/sm7xxfb.c
drivers/staging/speakup/Kconfig
drivers/staging/speakup/kobjects.c
drivers/staging/speakup/main.c
drivers/staging/speakup/speakup_acntpc.c
drivers/staging/speakup/speakup_apollo.c
drivers/staging/speakup/speakup_audptr.c
drivers/staging/speakup/varhandlers.c
drivers/staging/tidspbridge/rmgr/dspdrv.c
drivers/staging/usbip/stub_dev.c
drivers/staging/usbip/stub_main.c
drivers/staging/usbip/userspace/configure.ac
drivers/staging/usbip/userspace/doc/usbip.8
drivers/staging/usbip/userspace/doc/usbipd.8
drivers/staging/usbip/userspace/src/usbip_network.c
drivers/staging/usbip/userspace/src/usbip_network.h
drivers/staging/usbip/userspace/src/usbipd.c
drivers/staging/usbip/vhci_hcd.c
drivers/staging/vt6655/80211mgr.c
drivers/staging/vt6655/aes_ccmp.c
drivers/staging/vt6655/bssdb.c
drivers/staging/vt6655/device_main.c
drivers/staging/vt6655/dpc.c
drivers/staging/vt6655/hostap.c
drivers/staging/vt6655/iwctl.c
drivers/staging/vt6655/key.c
drivers/staging/vt6655/michael.h
drivers/staging/vt6655/rf.c
drivers/staging/vt6655/vntwifi.c
drivers/staging/vt6655/wcmd.c
drivers/staging/vt6655/wctl.c
drivers/staging/vt6655/wmgr.c
drivers/staging/vt6655/wpactl.c
drivers/staging/vt6655/wroute.c
drivers/staging/vt6655/wroute.h
drivers/staging/vt6656/bssdb.c
drivers/staging/vt6656/bssdb.h
drivers/staging/vt6656/channel.c
drivers/staging/vt6656/desc.h
drivers/staging/vt6656/device.h
drivers/staging/vt6656/dpc.c
drivers/staging/vt6656/dpc.h
drivers/staging/vt6656/firmware.c
drivers/staging/vt6656/hostap.c
drivers/staging/vt6656/iwctl.c
drivers/staging/vt6656/key.c
drivers/staging/vt6656/main_usb.c
drivers/staging/vt6656/power.c
drivers/staging/vt6656/rxtx.c
drivers/staging/vt6656/rxtx.h
drivers/staging/vt6656/usbpipe.c
drivers/staging/vt6656/wcmd.c
drivers/staging/vt6656/wcmd.h
drivers/staging/vt6656/wctl.c
drivers/staging/vt6656/wmgr.c
drivers/staging/vt6656/wmgr.h
drivers/staging/vt6656/wpactl.c
drivers/staging/winbond/mto.c
drivers/staging/winbond/mto.h
drivers/staging/winbond/phy_calibration.c
drivers/staging/winbond/reg.c
drivers/staging/winbond/wb35tx.c
drivers/staging/wlags49_h2/hcf.h
drivers/staging/wlags49_h2/sta_h2.c
drivers/staging/wlan-ng/cfg80211.c
drivers/staging/wlan-ng/hfa384x_usb.c
drivers/staging/wlan-ng/p80211netdev.h
drivers/staging/wlan-ng/p80211wep.c
drivers/staging/xgifb/XGI_main_26.c
drivers/staging/xgifb/vb_setmode.c
drivers/staging/xgifb/vb_table.h
drivers/staging/xillybus/Kconfig
drivers/staging/xillybus/xillybus_core.c
drivers/staging/xillybus/xillybus_of.c
drivers/staging/xillybus/xillybus_pcie.c
drivers/staging/zsmalloc/Kconfig
include/linux/hid-sensor-hub.h
include/linux/iio/buffer.h
include/linux/iio/common/st_sensors.h
include/linux/iio/consumer.h
include/linux/iio/events.h
include/linux/iio/iio.h
include/linux/iio/sysfs.h
include/linux/iio/types.h
include/linux/mfd/ti_am335x_tscadc.h

index 39c8de0e53d00924630c789e27c9e6c10af5e960..b20e829d350f7fa207760fd4c43c6f9b7db7cb60 100644 (file)
@@ -79,7 +79,7 @@ Description:
                correspond to externally available input one of the named
                versions may be used. The number must always be specified and
                unique to allow association with event codes. Units after
-               application of scale and offset are microvolts.
+               application of scale and offset are millivolts.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_raw
 KernelVersion: 2.6.35
@@ -90,7 +90,7 @@ Description:
                physically equivalent inputs when non differential readings are
                separately available. In differential only parts, then all that
                is required is a consistent labeling.  Units after application
-               of scale and offset are microvolts.
+               of scale and offset are millivolts.
 
 What:          /sys/bus/iio/devices/iio:deviceX/in_capacitanceY_raw
 KernelVersion: 3.2
@@ -537,6 +537,62 @@ Description:
                value is in raw device units or in processed units (as _raw
                and _input do on sysfs direct channel read attributes).
 
+What:          /sys/.../events/in_accel_x_thresh_rising_hysteresis
+What:          /sys/.../events/in_accel_x_thresh_falling_hysteresis
+What:          /sys/.../events/in_accel_x_thresh_either_hysteresis
+What:          /sys/.../events/in_accel_y_thresh_rising_hysteresis
+What:          /sys/.../events/in_accel_y_thresh_falling_hysteresis
+What:          /sys/.../events/in_accel_y_thresh_either_hysteresis
+What:          /sys/.../events/in_accel_z_thresh_rising_hysteresis
+What:          /sys/.../events/in_accel_z_thresh_falling_hysteresis
+What:          /sys/.../events/in_accel_z_thresh_either_hysteresis
+What:          /sys/.../events/in_anglvel_x_thresh_rising_hysteresis
+What:          /sys/.../events/in_anglvel_x_thresh_falling_hysteresis
+What:          /sys/.../events/in_anglvel_x_thresh_either_hysteresis
+What:          /sys/.../events/in_anglvel_y_thresh_rising_hysteresis
+What:          /sys/.../events/in_anglvel_y_thresh_falling_hysteresis
+What:          /sys/.../events/in_anglvel_y_thresh_either_hysteresis
+What:          /sys/.../events/in_anglvel_z_thresh_rising_hysteresis
+What:          /sys/.../events/in_anglvel_z_thresh_falling_hysteresis
+What:          /sys/.../events/in_anglvel_z_thresh_either_hysteresis
+What:          /sys/.../events/in_magn_x_thresh_rising_hysteresis
+What:          /sys/.../events/in_magn_x_thresh_falling_hysteresis
+What:          /sys/.../events/in_magn_x_thresh_either_hysteresis
+What:          /sys/.../events/in_magn_y_thresh_rising_hysteresis
+What:          /sys/.../events/in_magn_y_thresh_falling_hysteresis
+What:          /sys/.../events/in_magn_y_thresh_either_hysteresis
+What:          /sys/.../events/in_magn_z_thresh_rising_hysteresis
+What:          /sys/.../events/in_magn_z_thresh_falling_hysteresis
+What:          /sys/.../events/in_magn_z_thresh_either_hysteresis
+What:          /sys/.../events/in_voltageY_thresh_rising_hysteresis
+What:          /sys/.../events/in_voltageY_thresh_falling_hysteresis
+What:          /sys/.../events/in_voltageY_thresh_either_hysteresis
+What:          /sys/.../events/in_tempY_thresh_rising_hysteresis
+What:          /sys/.../events/in_tempY_thresh_falling_hysteresis
+What:          /sys/.../events/in_tempY_thresh_either_hysteresis
+What:          /sys/.../events/in_illuminance0_thresh_falling_hysteresis
+what:          /sys/.../events/in_illuminance0_thresh_rising_hysteresis
+what:          /sys/.../events/in_illuminance0_thresh_either_hysteresis
+what:          /sys/.../events/in_proximity0_thresh_falling_hysteresis
+what:          /sys/.../events/in_proximity0_thresh_rising_hysteresis
+what:          /sys/.../events/in_proximity0_thresh_either_hysteresis
+KernelVersion: 3.13
+Contact:       linux-iio@vger.kernel.org
+Description:
+               Specifies the hysteresis of threshold that the device is comparing
+               against for the events enabled by
+               <type>Y[_name]_thresh[_(rising|falling)]_hysteresis.
+               If separate attributes exist for the two directions, but
+               direction is not specified for this attribute, then a single
+               hysteresis value applies to both directions.
+               For falling events the hysteresis is added to the _value attribute for
+               this event to get the upper threshold for when the event goes back to
+               normal, for rising events the hysteresis is subtracted from the _value
+               attribute. E.g. if in_voltage0_raw_thresh_rising_value is set to 1200
+               and in_voltage0_raw_thresh_rising_hysteresis is set to 50. The event
+               will get activated once in_voltage0_raw goes above 1200 and will become
+               deactived again once the value falls below 1150.
+
 What:          /sys/.../events/in_accel_x_raw_roc_rising_value
 What:          /sys/.../events/in_accel_x_raw_roc_falling_value
 What:          /sys/.../events/in_accel_y_raw_roc_rising_value
@@ -811,3 +867,14 @@ Description:
                Writing '1' stores the current device configuration into
                on-chip EEPROM. After power-up or chip reset the device will
                automatically load the saved configuration.
+
+What:          /sys/.../iio:deviceX/in_intensity_red_integration_time
+What:          /sys/.../iio:deviceX/in_intensity_green_integration_time
+What:          /sys/.../iio:deviceX/in_intensity_blue_integration_time
+What:          /sys/.../iio:deviceX/in_intensity_clear_integration_time
+What:          /sys/.../iio:deviceX/in_illuminance_integration_time
+KernelVersion: 3.12
+Contact:       linux-iio@vger.kernel.org
+Description:
+               This attribute is used to get/set the integration time in
+               seconds.
index 723c205cb10d840e13a75be509ff0a06c37721bc..d1061469f63d9efec6a7265892bdbd6d9459d021 100644 (file)
@@ -7,7 +7,6 @@ Required properties:
   - interrupts: Should contain the IRQ line for the ADC
   - atmel,adc-channels-used: Bitmask of the channels muxed and enable for this
     device
-  - atmel,adc-num-channels: Number of channels available in the ADC
   - atmel,adc-startup-time: Startup Time of the ADC in microseconds as
     defined in the datasheet
   - atmel,adc-vref: Reference voltage in millivolts for the conversions
@@ -24,6 +23,13 @@ Optional properties:
                       resolution will be used.
   - atmel,adc-sleep-mode: Boolean to enable sleep mode when no conversion
   - atmel,adc-sample-hold-time: Sample and Hold Time in microseconds
+  - atmel,adc-ts-wires: Number of touch screen wires. Should be 4 or 5. If this
+                        value is set, then adc driver will enable touch screen
+                        support.
+    NOTE: when adc touch screen enabled, the adc hardware trigger will be
+          disabled. Since touch screen will occupied the trigger register.
+  - atmel,adc-ts-pressure-threshold: a pressure threshold for touchscreen. It
+                                     make touch detect more precision.
  
 Optional trigger Nodes:
   - Required properties:
diff --git a/Documentation/devicetree/bindings/iio/light/cm36651.txt b/Documentation/devicetree/bindings/iio/light/cm36651.txt
new file mode 100644 (file)
index 0000000..c03e19d
--- /dev/null
@@ -0,0 +1,26 @@
+* Capella CM36651 I2C Proximity and Color Light sensor
+
+Required properties:
+- compatible: must be "capella,cm36651"
+- reg: the I2C address of the device
+- interrupts: interrupt-specifier for the sole interrupt
+             generated by the device
+- vled-supply: regulator for the IR LED. IR_LED is a part
+             of the cm36651 for proximity detection.
+             As covered in ../../regulator/regulator.txt
+
+Example:
+
+       i2c_cm36651: i2c-gpio {
+               /* ... */
+
+               cm36651@18 {
+                       compatible = "capella,cm36651";
+                       reg = <0x18>;
+                       interrupt-parent = <&gpx0>;
+                       interrupts = <2 0>;
+                       vled-supply = <&ps_als_reg>;
+               };
+
+               /* ... */
+       };
diff --git a/Documentation/devicetree/bindings/iio/light/gp2ap020a00f.txt b/Documentation/devicetree/bindings/iio/light/gp2ap020a00f.txt
new file mode 100644 (file)
index 0000000..9231c82
--- /dev/null
@@ -0,0 +1,21 @@
+* Sharp GP2AP020A00F I2C Proximity/ALS sensor
+
+The proximity detector sensor requires power supply
+for its built-in led. It is also defined by this binding.
+
+Required properties:
+
+  - compatible : should be "sharp,gp2ap020a00f"
+  - reg : the I2C slave address of the light sensor
+  - interrupts : interrupt specifier for the sole interrupt generated
+                by the device
+  - vled-supply : VLED power supply, as covered in ../regulator/regulator.txt
+
+Example:
+
+gp2ap020a00f@39 {
+       compatible = "sharp,gp2ap020a00f";
+       reg = <0x39>;
+       interrupts = <2 0>;
+       vled-supply = <...>;
+};
index 46882058b59b54a12e457a72c1ed81ae62c90651..ee05dc3906941a10c5f20546e59b09e77bdf9c7b 100644 (file)
@@ -1,7 +1,8 @@
 * Freescale i.MX28 LRADC device driver
 
 Required properties:
-- compatible: Should be "fsl,imx28-lradc"
+- compatible: Should be "fsl,imx23-lradc" for i.MX23 SoC and "fsl,imx28-lradc"
+              for i.MX28 SoC
 - reg: Address and length of the register set for the device
 - interrupts: Should contain the LRADC interrupts
 
@@ -9,13 +10,38 @@ Optional properties:
 - fsl,lradc-touchscreen-wires: Number of wires used to connect the touchscreen
                                to LRADC. Valid value is either 4 or 5. If this
                                property is not present, then the touchscreen is
-                               disabled.
+                               disabled. 5 wires is valid for i.MX28 SoC only.
+- fsl,ave-ctrl: number of samples per direction to calculate an average value.
+                Allowed value is 1 ... 31, default is 4
+- fsl,ave-delay: delay between consecutive samples. Allowed value is
+                 1 ... 2047. It is used if 'fsl,ave-ctrl' > 1, counts at
+                 2 kHz and its default is 2 (= 1 ms)
+- fsl,settling: delay between plate switch to next sample. Allowed value is
+                1 ... 2047. It counts at 2 kHz and its default is
+                10 (= 5 ms)
 
-Examples:
+Example for i.MX23 SoC:
+
+       lradc@80050000 {
+               compatible = "fsl,imx23-lradc";
+               reg = <0x80050000 0x2000>;
+               interrupts = <36 37 38 39 40 41 42 43 44>;
+               status = "okay";
+               fsl,lradc-touchscreen-wires = <4>;
+               fsl,ave-ctrl = <4>;
+               fsl,ave-delay = <2>;
+               fsl,settling = <10>;
+       };
+
+Example for i.MX28 SoC:
 
        lradc@80050000 {
                compatible = "fsl,imx28-lradc";
                reg = <0x80050000 0x2000>;
-               interrupts = <10 14 15 16 17 18 19
-                               20 21 22 23 24 25>;
+               interrupts = <10 14 15 16 17 18 19 20 21 22 23 24 25>;
+               status = "okay";
+               fsl,lradc-touchscreen-wires = <5>;
+               fsl,ave-ctrl = <4>;
+               fsl,ave-delay = <2>;
+               fsl,settling = <10>;
        };
index 2956800f0240c8b3e48c9427151220ef2fc39fc1..04eab45dd14816280f3acbd63e2f69d08b12e277 100644 (file)
@@ -15,6 +15,7 @@ atmel Atmel Corporation
 avago  Avago Technologies
 bosch  Bosch Sensortec GmbH
 brcm   Broadcom Corporation
+capella        Capella Microsystems, Inc
 cavium Cavium, Inc.
 chrp   Common Hardware Reference Platform
 cirrus Cirrus Logic, Inc.
index 0ffe927dbbd906f52be196a9c36a35d6c286889c..40cf7cd5fa0e6f35368649dee282d802b6b0da92 100644 (file)
@@ -4247,7 +4247,7 @@ S:        Maintained
 F:     drivers/media/rc/iguanair.c
 
 IIO SUBSYSTEM AND DRIVERS
-M:     Jonathan Cameron <jic23@cam.ac.uk>
+M:     Jonathan Cameron <jic23@kernel.org>
 L:     linux-iio@vger.kernel.org
 S:     Maintained
 F:     drivers/iio/
@@ -4784,6 +4784,13 @@ S:       Maintained
 F:     Documentation/hwmon/k8temp
 F:     drivers/hwmon/k8temp.c
 
+KTAP
+M:     Jovi Zhangwei <jovi.zhangwei@gmail.com>
+W:     http://www.ktap.org
+L:     ktap@freelists.org
+S:     Maintained
+F:     drivers/staging/ktap/
+
 KCONFIG
 M:     Michal Marek <mmarek@suse.cz>
 L:     linux-kbuild@vger.kernel.org
@@ -8034,7 +8041,7 @@ S:        Maintained
 F:     drivers/staging/media/go7007/
 
 STAGING - INDUSTRIAL IO
-M:     Jonathan Cameron <jic23@cam.ac.uk>
+M:     Jonathan Cameron <jic23@kernel.org>
 L:     linux-iio@vger.kernel.org
 S:     Odd Fixes
 F:     drivers/staging/iio/
index 28b5ce289662b8c74955ecb38e023a6b773cb7b0..07caf767d4289557d8696362fdb1c77f783f0a52 100644 (file)
                                reg = <0x80050000 0x2000>;
                                interrupts = <36 37 38 39 40 41 42 43 44>;
                                status = "disabled";
+                               clocks = <&clks 26>;
                        };
 
                        spdif@80054000 {
index 15715d921d14417a5f0e1e8fe76047410239aaa9..aa33393903a87cec3bcef3bb7f5138a779230d96 100644 (file)
 
                        lradc@80050000 {
                                status = "okay";
+                               fsl,lradc-touchscreen-wires = <4>;
+                               fsl,ave-ctrl = <4>;
+                               fsl,ave-delay = <2>;
+                               fsl,settling = <10>;
                        };
 
                        i2c0: i2c@80058000 {
index 7363fded95ee9411d21faf35c4a242ccd5aeb592..175deefb048b4349762d73ceaaebfdd0d6309080 100644 (file)
                                interrupts = <10 14 15 16 17 18 19
                                                20 21 22 23 24 25>;
                                status = "disabled";
+                               clocks = <&clks 41>;
                        };
 
                        spdif: spdif@80054000 {
index 048a57f76bd3bbbac837e543cd4a4a7048b5e3e0..c287307b9a3ba1a3efcd7b0c09605fef8c4c00e7 100644 (file)
 #define AT91_ADC_IER           0x24            /* Interrupt Enable Register */
 #define AT91_ADC_IDR           0x28            /* Interrupt Disable Register */
 #define AT91_ADC_IMR           0x2C            /* Interrupt Mask Register */
+#define                AT91_ADC_IER_PEN        (1 << 29)
+#define                AT91_ADC_IER_NOPEN      (1 << 30)
+#define                AT91_ADC_IER_XRDY       (1 << 20)
+#define                AT91_ADC_IER_YRDY       (1 << 21)
+#define                AT91_ADC_IER_PRDY       (1 << 22)
+#define                AT91_ADC_ISR_PENS       (1 << 31)
 
 #define AT91_ADC_CHR(n)                (0x30 + ((n) * 4))      /* Channel Data Register N */
 #define                AT91_ADC_DATA           (0x3ff)
 
 #define AT91_ADC_CDR0_9X5      (0x50)                  /* Channel Data Register 0 for 9X5 */
 
+#define AT91_ADC_ACR           0x94    /* Analog Control Register */
+#define                AT91_ADC_ACR_PENDETSENS (0x3 << 0)      /* pull-up resistor */
+
+#define AT91_ADC_TSMR          0xB0
+#define                AT91_ADC_TSMR_TSMODE    (3 << 0)        /* Touch Screen Mode */
+#define                        AT91_ADC_TSMR_TSMODE_NONE               (0 << 0)
+#define                        AT91_ADC_TSMR_TSMODE_4WIRE_NO_PRESS     (1 << 0)
+#define                        AT91_ADC_TSMR_TSMODE_4WIRE_PRESS        (2 << 0)
+#define                        AT91_ADC_TSMR_TSMODE_5WIRE              (3 << 0)
+#define                AT91_ADC_TSMR_TSAV      (3 << 4)        /* Averages samples */
+#define                        AT91_ADC_TSMR_TSAV_(x)          ((x) << 4)
+#define                AT91_ADC_TSMR_SCTIM     (0x0f << 16)    /* Switch closure time */
+#define                AT91_ADC_TSMR_PENDBC    (0x0f << 28)    /* Pen Debounce time */
+#define                        AT91_ADC_TSMR_PENDBC_(x)        ((x) << 28)
+#define                AT91_ADC_TSMR_NOTSDMA   (1 << 22)       /* No Touchscreen DMA */
+#define                AT91_ADC_TSMR_PENDET_DIS        (0 << 24)       /* Pen contact detection disable */
+#define                AT91_ADC_TSMR_PENDET_ENA        (1 << 24)       /* Pen contact detection enable */
+
+#define AT91_ADC_TSXPOSR       0xB4
+#define AT91_ADC_TSYPOSR       0xB8
+#define AT91_ADC_TSPRESSR      0xBC
+
 #define AT91_ADC_TRGR_9260     AT91_ADC_MR
 #define AT91_ADC_TRGR_9G45     0x08
 #define AT91_ADC_TRGR_9X5      0xC0
 
+/* Trigger Register bit field */
+#define                AT91_ADC_TRGR_TRGPER    (0xffff << 16)
+#define                        AT91_ADC_TRGR_TRGPER_(x)        ((x) << 16)
+#define                AT91_ADC_TRGR_TRGMOD    (0x7 << 0)
+#define                        AT91_ADC_TRGR_MOD_PERIOD_TRIG   (5 << 0)
+
 #endif
index 10e1581022cfdea4acd4e5431ea43155e83898f0..88fc5aefcd964b2f8b6c83476ca7d308066069f1 100644 (file)
@@ -465,6 +465,39 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
        return 1;
 }
 
+int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev)
+{
+       int ret = 0;
+       struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);
+
+       mutex_lock(&data->mutex);
+       if (!hsdev->ref_cnt) {
+               ret = hid_hw_open(hsdev->hdev);
+               if (ret) {
+                       hid_err(hsdev->hdev, "failed to open hid device\n");
+                       mutex_unlock(&data->mutex);
+                       return ret;
+               }
+       }
+       hsdev->ref_cnt++;
+       mutex_unlock(&data->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(sensor_hub_device_open);
+
+void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev)
+{
+       struct sensor_hub_data *data =  hid_get_drvdata(hsdev->hdev);
+
+       mutex_lock(&data->mutex);
+       hsdev->ref_cnt--;
+       if (!hsdev->ref_cnt)
+               hid_hw_close(hsdev->hdev);
+       mutex_unlock(&data->mutex);
+}
+EXPORT_SYMBOL_GPL(sensor_hub_device_close);
+
 static int sensor_hub_probe(struct hid_device *hdev,
                                const struct hid_device_id *id)
 {
@@ -506,12 +539,6 @@ static int sensor_hub_probe(struct hid_device *hdev,
                hid_err(hdev, "hw start failed\n");
                return ret;
        }
-       ret = hid_hw_open(hdev);
-       if (ret) {
-               hid_err(hdev, "failed to open input interrupt pipe\n");
-               goto err_stop_hw;
-       }
-
        INIT_LIST_HEAD(&sd->dyn_callback_list);
        sd->hid_sensor_client_cnt = 0;
        report_enum = &hdev->report_enum[HID_INPUT_REPORT];
@@ -520,7 +547,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
        if (dev_cnt > HID_MAX_PHY_DEVICES) {
                hid_err(hdev, "Invalid Physical device count\n");
                ret = -EINVAL;
-               goto err_close;
+               goto err_stop_hw;
        }
        sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt *
                                                sizeof(struct mfd_cell),
@@ -528,7 +555,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
        if (sd->hid_sensor_hub_client_devs == NULL) {
                hid_err(hdev, "Failed to allocate memory for mfd cells\n");
                        ret = -ENOMEM;
-                       goto err_close;
+                       goto err_stop_hw;
        }
        list_for_each_entry(report, &report_enum->report_list, list) {
                hid_dbg(hdev, "Report id:%x\n", report->id);
@@ -565,8 +592,6 @@ err_free_names:
        for (i = 0; i < sd->hid_sensor_client_cnt ; ++i)
                kfree(sd->hid_sensor_hub_client_devs[i].name);
        kfree(sd->hid_sensor_hub_client_devs);
-err_close:
-       hid_hw_close(hdev);
 err_stop_hw:
        hid_hw_stop(hdev);
 
index 81e3dc260993124981d45cacb9e472e9221d7b8a..28b39283bccffaad1fdd13950aaa62dabd2d7248 100644 (file)
@@ -471,13 +471,10 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct bma180_data *data = iio_priv(indio_dev);
+       int64_t time_ns = iio_get_time_ns();
        int bit, ret, i = 0;
 
        mutex_lock(&data->mutex);
-       if (indio_dev->scan_timestamp) {
-               ret = indio_dev->scan_bytes / sizeof(s64) - 1;
-               ((s64 *)data->buff)[ret] = iio_get_time_ns();
-       }
 
        for_each_set_bit(bit, indio_dev->buffer->scan_mask,
                         indio_dev->masklength) {
@@ -490,7 +487,7 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
        }
        mutex_unlock(&data->mutex);
 
-       iio_push_to_buffers(indio_dev, (u8 *)data->buff);
+       iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns);
 err:
        iio_trigger_notify_done(indio_dev->trig);
 
index 46d22f3fb1a9bb0c3fb2259b6399fd1642d107d7..dcda17395c4e68f31f3382cd0c393a5845b025c5 100644 (file)
@@ -182,10 +182,11 @@ static const struct iio_info accel_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+       int len)
 {
        dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+       iio_push_to_buffers(indio_dev, data);
 }
 
 /* Callback handler to send event after all samples are received and captured */
@@ -200,7 +201,7 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
                                accel_state->common_attributes.data_ready);
        if (accel_state->common_attributes.data_ready)
                hid_sensor_push_data(indio_dev,
-                               (u8 *)accel_state->accel_val,
+                               accel_state->accel_val,
                                sizeof(accel_state->accel_val));
 
        return 0;
index d9b350756f90f11d1bc77cd88362fe45639d295e..a1e642ee13d6a4f8af5eb0f6a9c92bafe51460d9 100644 (file)
@@ -32,16 +32,7 @@ int st_accel_trig_set_state(struct iio_trigger *trig, bool state)
 
 static int st_accel_buffer_preenable(struct iio_dev *indio_dev)
 {
-       int err;
-
-       err = st_sensors_set_enable(indio_dev, true);
-       if (err < 0)
-               goto st_accel_set_enable_error;
-
-       err = iio_sw_buffer_preenable(indio_dev);
-
-st_accel_set_enable_error:
-       return err;
+       return st_sensors_set_enable(indio_dev, true);
 }
 
 static int st_accel_buffer_postenable(struct iio_dev *indio_dev)
index 1458343f6f3fac94f5aa882df1e88d2d9ac37ad1..38caedc76b98f20520f9be751fabc15e90b03793 100644 (file)
@@ -452,8 +452,9 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
 int st_accel_common_probe(struct iio_dev *indio_dev,
                                struct st_sensors_platform_data *plat_data)
 {
-       int err;
        struct st_sensor_data *adata = iio_priv(indio_dev);
+       int irq = adata->get_irq_data_ready(indio_dev);
+       int err;
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &accel_info;
@@ -461,7 +462,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
        err = st_sensors_check_device_support(indio_dev,
                                ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
        if (err < 0)
-               goto st_accel_common_probe_error;
+               return err;
 
        adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
        adata->multiread_bit = adata->sensor->multi_read_bit;
@@ -478,13 +479,13 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
 
        err = st_sensors_init_sensor(indio_dev, plat_data);
        if (err < 0)
-               goto st_accel_common_probe_error;
+               return err;
 
-       if (adata->get_irq_data_ready(indio_dev) > 0) {
-               err = st_accel_allocate_ring(indio_dev);
-               if (err < 0)
-                       goto st_accel_common_probe_error;
+       err = st_accel_allocate_ring(indio_dev);
+       if (err < 0)
+               return err;
 
+       if (irq > 0) {
                err = st_sensors_allocate_trigger(indio_dev,
                                                 ST_ACCEL_TRIGGER_OPS);
                if (err < 0)
@@ -495,15 +496,14 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
        if (err)
                goto st_accel_device_register_error;
 
-       return err;
+       return 0;
 
 st_accel_device_register_error:
-       if (adata->get_irq_data_ready(indio_dev) > 0)
+       if (irq > 0)
                st_sensors_deallocate_trigger(indio_dev);
 st_accel_probe_trigger_error:
-       if (adata->get_irq_data_ready(indio_dev) > 0)
-               st_accel_deallocate_ring(indio_dev);
-st_accel_common_probe_error:
+       st_accel_deallocate_ring(indio_dev);
+
        return err;
 }
 EXPORT_SYMBOL(st_accel_common_probe);
@@ -513,10 +513,10 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
        struct st_sensor_data *adata = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (adata->get_irq_data_ready(indio_dev) > 0) {
+       if (adata->get_irq_data_ready(indio_dev) > 0)
                st_sensors_deallocate_trigger(indio_dev);
-               st_accel_deallocate_ring(indio_dev);
-       }
+
+       st_accel_deallocate_ring(indio_dev);
 }
 EXPORT_SYMBOL(st_accel_common_remove);
 
index 09371cbc9dc123d1a1c929d109202a2a6be68f91..2209f28441e94d013ef435a100c17d6920677e08 100644 (file)
@@ -145,6 +145,16 @@ config MCP320X
          This driver can also be built as a module. If so, the module will be
          called mcp320x.
 
+config MCP3422
+       tristate "Microchip Technology MCP3422/3/4 driver"
+       depends on I2C
+       help
+         Say yes here to build support for Microchip Technology's MCP3422,
+         MCP3423 or MCP3424 analog to digital converters.
+
+         This driver can also be built as a module. If so, the module will be
+         called mcp3422.
+
 config NAU7802
        tristate "Nuvoton NAU7802 ADC driver"
        depends on I2C
@@ -167,6 +177,8 @@ config TI_ADC081C
 config TI_AM335X_ADC
        tristate "TI's AM335X ADC driver"
        depends on MFD_TI_AM335X_TSCADC
+       select IIO_BUFFER
+       select IIO_KFIFO_BUF
        help
          Say yes here to build support for Texas Instruments ADC
          driver which is also a MFD client.
index 33656ef7d1f60fbd8b16c0c4bf5fa61ef2cc2506..ba9a10a24cd03ee4d80f4bc2e0a9fd56b106d908 100644 (file)
@@ -16,6 +16,7 @@ obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
 obj-$(CONFIG_MCP320X) += mcp320x.o
+obj-$(CONFIG_MCP3422) += mcp3422.o
 obj-$(CONFIG_NAU7802) += nau7802.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
index 371731df1634b97a471f51fd67f1a8fbbddef091..58e945594c7bb7e484588820517c1b067b5c2521 100644 (file)
@@ -27,7 +27,7 @@
 struct ad7266_state {
        struct spi_device       *spi;
        struct regulator        *reg;
-       unsigned long           vref_uv;
+       unsigned long           vref_mv;
 
        struct spi_transfer     single_xfer[3];
        struct spi_message      single_msg;
@@ -61,17 +61,7 @@ static int ad7266_powerdown(struct ad7266_state *st)
 static int ad7266_preenable(struct iio_dev *indio_dev)
 {
        struct ad7266_state *st = iio_priv(indio_dev);
-       int ret;
-
-       ret = ad7266_wakeup(st);
-       if (ret)
-               return ret;
-
-       ret = iio_sw_buffer_preenable(indio_dev);
-       if (ret)
-               ad7266_powerdown(st);
-
-       return ret;
+       return ad7266_wakeup(st);
 }
 
 static int ad7266_postdisable(struct iio_dev *indio_dev)
@@ -96,9 +86,8 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
 
        ret = spi_read(st->spi, st->data, 4);
        if (ret == 0) {
-               if (indio_dev->scan_timestamp)
-                       ((s64 *)st->data)[1] = pf->timestamp;
-               iio_push_to_buffers(indio_dev, (u8 *)st->data);
+               iio_push_to_buffers_with_timestamp(indio_dev, st->data,
+                           pf->timestamp);
        }
 
        iio_trigger_notify_done(indio_dev->trig);
@@ -157,7 +146,7 @@ static int ad7266_read_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int *val, int *val2, long m)
 {
        struct ad7266_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
+       unsigned long scale_mv;
        int ret;
 
        switch (m) {
@@ -175,16 +164,15 @@ static int ad7266_read_raw(struct iio_dev *indio_dev,
 
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_uv * 100);
+               scale_mv = st->vref_mv;
                if (st->mode == AD7266_MODE_DIFF)
-                       scale_uv *= 2;
+                       scale_mv *= 2;
                if (st->range == AD7266_RANGE_2VREF)
-                       scale_uv *= 2;
+                       scale_mv *= 2;
 
-               scale_uv >>= chan->scan_type.realbits;
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = scale_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_OFFSET:
                if (st->range == AD7266_RANGE_2VREF &&
                        st->mode != AD7266_MODE_DIFF)
@@ -293,7 +281,7 @@ static const struct iio_info ad7266_info = {
        .driver_module = THIS_MODULE,
 };
 
-static unsigned long ad7266_available_scan_masks[] = {
+static const unsigned long ad7266_available_scan_masks[] = {
        0x003,
        0x00c,
        0x030,
@@ -303,14 +291,14 @@ static unsigned long ad7266_available_scan_masks[] = {
        0x000,
 };
 
-static unsigned long ad7266_available_scan_masks_diff[] = {
+static const unsigned long ad7266_available_scan_masks_diff[] = {
        0x003,
        0x00c,
        0x030,
        0x000,
 };
 
-static unsigned long ad7266_available_scan_masks_fixed[] = {
+static const unsigned long ad7266_available_scan_masks_fixed[] = {
        0x003,
        0x000,
 };
@@ -318,7 +306,7 @@ static unsigned long ad7266_available_scan_masks_fixed[] = {
 struct ad7266_chan_info {
        const struct iio_chan_spec *channels;
        unsigned int num_channels;
-       unsigned long *scan_masks;
+       const unsigned long *scan_masks;
 };
 
 #define AD7266_CHAN_INFO_INDEX(_differential, _signed, _fixed) \
@@ -415,10 +403,10 @@ static int ad7266_probe(struct spi_device *spi)
                if (ret < 0)
                        goto error_disable_reg;
 
-               st->vref_uv = ret;
+               st->vref_mv = ret / 1000;
        } else {
                /* Use internal reference */
-               st->vref_uv = 2500000;
+               st->vref_mv = 2500;
        }
 
        if (pdata) {
index 85d1481c312f67b1d84208f9003e04c0a9ee6891..2a3b65c74af9aa32543dc4d248216f31646a1c08 100644 (file)
@@ -159,20 +159,14 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad7298_state *st = iio_priv(indio_dev);
-       s64 time_ns = 0;
        int b_sent;
 
        b_sent = spi_sync(st->spi, &st->ring_msg);
        if (b_sent)
                goto done;
 
-       if (indio_dev->scan_timestamp) {
-               time_ns = iio_get_time_ns();
-               memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
-                       &time_ns, sizeof(time_ns));
-       }
-
-       iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf);
+       iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+               iio_get_time_ns());
 
 done:
        iio_trigger_notify_done(indio_dev->trig);
index 6d2b1d8d1a1f001dbec29f88633ba90fffe15e90..d141d452c3d1081d4bea64ff01e5b38e855fcd9d 100644 (file)
@@ -64,19 +64,14 @@ static irqreturn_t ad7476_trigger_handler(int irq, void  *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad7476_state *st = iio_priv(indio_dev);
-       s64 time_ns;
        int b_sent;
 
        b_sent = spi_sync(st->spi, &st->msg);
        if (b_sent < 0)
                goto done;
 
-       time_ns = iio_get_time_ns();
-
-       if (indio_dev->scan_timestamp)
-               ((s64 *)st->data)[1] = time_ns;
-
-       iio_push_to_buffers(indio_dev, st->data);
+       iio_push_to_buffers_with_timestamp(indio_dev, st->data,
+               iio_get_time_ns());
 done:
        iio_trigger_notify_done(indio_dev->trig);
 
@@ -132,10 +127,9 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
                } else {
                        scale_uv = st->chip_info->int_vref_uv;
                }
-               scale_uv >>= chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = scale_uv / 1000;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
index c20203577d2d1e38da820299fba5aca0d10a0c37..c19f8fd1b4b7ac9ba5c2b216d5aa7be362200859 100644 (file)
@@ -202,7 +202,6 @@ static int ad7791_read_raw(struct iio_dev *indio_dev,
 {
        struct ad7791_state *st = iio_priv(indio_dev);
        bool unipolar = !!(st->mode & AD7791_MODE_UNIPOLAR);
-       unsigned long long scale_pv;
 
        switch (info) {
        case IIO_CHAN_INFO_RAW:
@@ -220,23 +219,26 @@ static int ad7791_read_raw(struct iio_dev *indio_dev,
        case IIO_CHAN_INFO_SCALE:
                /* The monitor channel uses an internal reference. */
                if (chan->address == AD7791_CH_AVDD_MONITOR) {
-                       scale_pv = 5850000000000ULL;
+                       /*
+                        * The signal is attenuated by a factor of 5 and
+                        * compared against a 1.17V internal reference.
+                        */
+                       *val = 1170 * 5;
                } else {
                        int voltage_uv;
 
                        voltage_uv = regulator_get_voltage(st->reg);
                        if (voltage_uv < 0)
                                return voltage_uv;
-                       scale_pv = (unsigned long long)voltage_uv * 1000000;
+
+                       *val = voltage_uv / 1000;
                }
                if (unipolar)
-                       scale_pv >>= chan->scan_type.realbits;
+                       *val2 = chan->scan_type.realbits;
                else
-                       scale_pv >>= chan->scan_type.realbits - 1;
-               *val2 = do_div(scale_pv, 1000000000);
-               *val = scale_pv;
+                       *val2 = chan->scan_type.realbits - 1;
 
-               return IIO_VAL_INT_PLUS_NANO;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
 
        return -EINVAL;
index 9dd077b78759047ae39fde5a8d0a2b589b487b22..acb7f90359a3460371c9d1e8a00cd15c3a77a26d 100644 (file)
@@ -78,11 +78,6 @@ enum ad7887_supported_device_ids {
 static int ad7887_ring_preenable(struct iio_dev *indio_dev)
 {
        struct ad7887_state *st = iio_priv(indio_dev);
-       int ret;
-
-       ret = iio_sw_buffer_preenable(indio_dev);
-       if (ret < 0)
-               return ret;
 
        /* We know this is a single long so can 'cheat' */
        switch (*indio_dev->active_scan_mask) {
@@ -121,20 +116,14 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad7887_state *st = iio_priv(indio_dev);
-       s64 time_ns;
        int b_sent;
 
        b_sent = spi_sync(st->spi, st->ring_msg);
        if (b_sent)
                goto done;
 
-       time_ns = iio_get_time_ns();
-
-       if (indio_dev->scan_timestamp)
-               memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
-                      &time_ns, sizeof(time_ns));
-
-       iio_push_to_buffers(indio_dev, st->data);
+       iio_push_to_buffers_with_timestamp(indio_dev, st->data,
+               iio_get_time_ns());
 done:
        iio_trigger_notify_done(indio_dev->trig);
 
index 4108dbb28c3d8edfa1b2e20134cf65e38951d55d..28732c28e8197a688c27d1d665458fae24c8a97f 100644 (file)
@@ -174,20 +174,14 @@ static irqreturn_t ad7923_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad7923_state *st = iio_priv(indio_dev);
-       s64 time_ns = 0;
        int b_sent;
 
        b_sent = spi_sync(st->spi, &st->ring_msg);
        if (b_sent)
                goto done;
 
-       if (indio_dev->scan_timestamp) {
-               time_ns = iio_get_time_ns();
-               memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
-                       &time_ns, sizeof(time_ns));
-       }
-
-       iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf);
+       iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+               iio_get_time_ns());
 
 done:
        iio_trigger_notify_done(indio_dev->trig);
index f0d6335ae08760d418f56ced0eaec227772fa1ce..e6fbd3e70981fca1a4d93d2c03891fcf1efde6c0 100644 (file)
@@ -368,10 +368,6 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
 
        memset(data, 0x00, 16);
 
-       /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp)
-               ((s64 *)data)[1] = pf->timestamp;
-
        reg_size = indio_dev->channels[0].scan_type.realbits +
                        indio_dev->channels[0].scan_type.shift;
        reg_size = DIV_ROUND_UP(reg_size, 8);
@@ -391,7 +387,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
                break;
        }
 
-       iio_push_to_buffers(indio_dev, (uint8_t *)data);
+       iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
 
        iio_trigger_notify_done(indio_dev->trig);
        sigma_delta->irq_dis = false;
@@ -401,7 +397,6 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
 }
 
 static const struct iio_buffer_setup_ops ad_sd_buffer_setup_ops = {
-       .preenable = &iio_sw_buffer_preenable,
        .postenable = &ad_sd_buffer_postenable,
        .predisable = &iio_triggered_buffer_predisable,
        .postdisable = &ad_sd_buffer_postdisable,
index 0f16b553e063f602e4e83104382827bb55cc72b2..17df74908db120a6e33e3f43a51fc4e67784da59 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #define at91_adc_writel(st, reg, val) \
        (writel_relaxed(val, st->reg_base + reg))
 
+#define DRIVER_NAME            "at91_adc"
+#define MAX_POS_BITS           12
+
+#define TOUCH_SAMPLE_PERIOD_US         2000    /* 2ms */
+#define TOUCH_PEN_DETECT_DEBOUNCE_US   200
+
 struct at91_adc_caps {
+       bool    has_ts;         /* Support touch screen */
+       bool    has_tsmr;       /* only at91sam9x5, sama5d3 have TSMR reg */
+       /*
+        * Numbers of sampling data will be averaged. Can be 0~3.
+        * Hardware can average (2 ^ ts_filter_average) sample data.
+        */
+       u8      ts_filter_average;
+       /* Pen Detection input pull-up resistor, can be 0~3 */
+       u8      ts_pen_detect_sensitivity;
+
+       /* startup time calculate function */
+       u32 (*calc_startup_ticks)(u8 startup_time, u32 adc_clk_khz);
+
+       u8      num_channels;
        struct at91_adc_reg_desc registers;
 };
 
+enum atmel_adc_ts_type {
+       ATMEL_ADC_TOUCHSCREEN_NONE = 0,
+       ATMEL_ADC_TOUCHSCREEN_4WIRE = 4,
+       ATMEL_ADC_TOUCHSCREEN_5WIRE = 5,
+};
+
 struct at91_adc_state {
        struct clk              *adc_clk;
        u16                     *buffer;
@@ -67,6 +94,26 @@ struct at91_adc_state {
        bool                    low_res;        /* the resolution corresponds to the lowest one */
        wait_queue_head_t       wq_data_avail;
        struct at91_adc_caps    *caps;
+
+       /*
+        * Following ADC channels are shared by touchscreen:
+        *
+        * CH0 -- Touch screen XP/UL
+        * CH1 -- Touch screen XM/UR
+        * CH2 -- Touch screen YP/LL
+        * CH3 -- Touch screen YM/Sense
+        * CH4 -- Touch screen LR(5-wire only)
+        *
+        * The bitfields below represents the reserved channel in the
+        * touchscreen mode.
+        */
+#define CHAN_MASK_TOUCHSCREEN_4WIRE    (0xf << 0)
+#define CHAN_MASK_TOUCHSCREEN_5WIRE    (0x1f << 0)
+       enum atmel_adc_ts_type  touchscreen_type;
+       struct input_dev        *ts_input;
+
+       u16                     ts_sample_period_val;
+       u32                     ts_pressure_threshold;
 };
 
 static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
@@ -83,13 +130,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
                j++;
        }
 
-       if (idev->scan_timestamp) {
-               s64 *timestamp = (s64 *)((u8 *)st->buffer +
-                                       ALIGN(j, sizeof(s64)));
-               *timestamp = pf->timestamp;
-       }
-
-       iio_push_to_buffers(idev, (u8 *)st->buffer);
+       iio_push_to_buffers_with_timestamp(idev, st->buffer, pf->timestamp);
 
        iio_trigger_notify_done(idev->trig);
 
@@ -101,14 +142,10 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t at91_adc_eoc_trigger(int irq, void *private)
+/* Handler for classic adc channel eoc trigger */
+void handle_adc_eoc_trigger(int irq, struct iio_dev *idev)
 {
-       struct iio_dev *idev = private;
        struct at91_adc_state *st = iio_priv(idev);
-       u32 status = at91_adc_readl(st, st->registers->status_register);
-
-       if (!(status & st->registers->drdy_mask))
-               return IRQ_HANDLED;
 
        if (iio_buffer_enabled(idev)) {
                disable_irq_nosync(irq);
@@ -118,6 +155,115 @@ static irqreturn_t at91_adc_eoc_trigger(int irq, void *private)
                st->done = true;
                wake_up_interruptible(&st->wq_data_avail);
        }
+}
+
+static int at91_ts_sample(struct at91_adc_state *st)
+{
+       unsigned int xscale, yscale, reg, z1, z2;
+       unsigned int x, y, pres, xpos, ypos;
+       unsigned int rxp = 1;
+       unsigned int factor = 1000;
+       struct iio_dev *idev = iio_priv_to_dev(st);
+
+       unsigned int xyz_mask_bits = st->res;
+       unsigned int xyz_mask = (1 << xyz_mask_bits) - 1;
+
+       /* calculate position */
+       /* x position = (x / xscale) * max, max = 2^MAX_POS_BITS - 1 */
+       reg = at91_adc_readl(st, AT91_ADC_TSXPOSR);
+       xpos = reg & xyz_mask;
+       x = (xpos << MAX_POS_BITS) - xpos;
+       xscale = (reg >> 16) & xyz_mask;
+       if (xscale == 0) {
+               dev_err(&idev->dev, "Error: xscale == 0!\n");
+               return -1;
+       }
+       x /= xscale;
+
+       /* y position = (y / yscale) * max, max = 2^MAX_POS_BITS - 1 */
+       reg = at91_adc_readl(st, AT91_ADC_TSYPOSR);
+       ypos = reg & xyz_mask;
+       y = (ypos << MAX_POS_BITS) - ypos;
+       yscale = (reg >> 16) & xyz_mask;
+       if (yscale == 0) {
+               dev_err(&idev->dev, "Error: yscale == 0!\n");
+               return -1;
+       }
+       y /= yscale;
+
+       /* calculate the pressure */
+       reg = at91_adc_readl(st, AT91_ADC_TSPRESSR);
+       z1 = reg & xyz_mask;
+       z2 = (reg >> 16) & xyz_mask;
+
+       if (z1 != 0)
+               pres = rxp * (x * factor / 1024) * (z2 * factor / z1 - factor)
+                       / factor;
+       else
+               pres = st->ts_pressure_threshold;       /* no pen contacted */
+
+       dev_dbg(&idev->dev, "xpos = %d, xscale = %d, ypos = %d, yscale = %d, z1 = %d, z2 = %d, press = %d\n",
+                               xpos, xscale, ypos, yscale, z1, z2, pres);
+
+       if (pres < st->ts_pressure_threshold) {
+               dev_dbg(&idev->dev, "x = %d, y = %d, pressure = %d\n",
+                                       x, y, pres / factor);
+               input_report_abs(st->ts_input, ABS_X, x);
+               input_report_abs(st->ts_input, ABS_Y, y);
+               input_report_abs(st->ts_input, ABS_PRESSURE, pres);
+               input_report_key(st->ts_input, BTN_TOUCH, 1);
+               input_sync(st->ts_input);
+       } else {
+               dev_dbg(&idev->dev, "pressure too low: not reporting\n");
+       }
+
+       return 0;
+}
+
+static irqreturn_t at91_adc_interrupt(int irq, void *private)
+{
+       struct iio_dev *idev = private;
+       struct at91_adc_state *st = iio_priv(idev);
+       u32 status = at91_adc_readl(st, st->registers->status_register);
+       const uint32_t ts_data_irq_mask =
+               AT91_ADC_IER_XRDY |
+               AT91_ADC_IER_YRDY |
+               AT91_ADC_IER_PRDY;
+
+       if (status & st->registers->drdy_mask)
+               handle_adc_eoc_trigger(irq, idev);
+
+       if (status & AT91_ADC_IER_PEN) {
+               at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN);
+               at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_NOPEN |
+                       ts_data_irq_mask);
+               /* Set up period trigger for sampling */
+               at91_adc_writel(st, st->registers->trigger_register,
+                       AT91_ADC_TRGR_MOD_PERIOD_TRIG |
+                       AT91_ADC_TRGR_TRGPER_(st->ts_sample_period_val));
+       } else if (status & AT91_ADC_IER_NOPEN) {
+               at91_adc_writel(st, st->registers->trigger_register, 0);
+               at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_NOPEN |
+                       ts_data_irq_mask);
+               at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN);
+
+               input_report_key(st->ts_input, BTN_TOUCH, 0);
+               input_sync(st->ts_input);
+       } else if ((status & ts_data_irq_mask) == ts_data_irq_mask) {
+               /* Now all touchscreen data is ready */
+
+               if (status & AT91_ADC_ISR_PENS) {
+                       /* validate data by pen contact */
+                       at91_ts_sample(st);
+               } else {
+                       /* triggered by event that is no pen contact, just read
+                        * them to clean the interrupt and discard all.
+                        */
+                       at91_adc_readl(st, AT91_ADC_TSXPOSR);
+                       at91_adc_readl(st, AT91_ADC_TSYPOSR);
+                       at91_adc_readl(st, AT91_ADC_TSPRESSR);
+               }
+       }
 
        return IRQ_HANDLED;
 }
@@ -127,6 +273,16 @@ static int at91_adc_channel_init(struct iio_dev *idev)
        struct at91_adc_state *st = iio_priv(idev);
        struct iio_chan_spec *chan_array, *timestamp;
        int bit, idx = 0;
+       unsigned long rsvd_mask = 0;
+
+       /* If touchscreen is enable, then reserve the adc channels */
+       if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE)
+               rsvd_mask = CHAN_MASK_TOUCHSCREEN_4WIRE;
+       else if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_5WIRE)
+               rsvd_mask = CHAN_MASK_TOUCHSCREEN_5WIRE;
+
+       /* set up the channel mask to reserve touchscreen channels */
+       st->channels_mask &= ~rsvd_mask;
 
        idev->num_channels = bitmap_weight(&st->channels_mask,
                                           st->num_channels) + 1;
@@ -279,7 +435,7 @@ static int at91_adc_trigger_init(struct iio_dev *idev)
        int i, ret;
 
        st->trig = devm_kzalloc(&idev->dev,
-                               st->trigger_number * sizeof(st->trig),
+                               st->trigger_number * sizeof(*st->trig),
                                GFP_KERNEL);
 
        if (st->trig == NULL) {
@@ -372,9 +528,9 @@ static int at91_adc_read_raw(struct iio_dev *idev,
                return IIO_VAL_INT;
 
        case IIO_CHAN_INFO_SCALE:
-               *val = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val2 = 0;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        default:
                break;
        }
@@ -434,8 +590,80 @@ ret:
        return ret;
 }
 
+static u32 calc_startup_ticks_9260(u8 startup_time, u32 adc_clk_khz)
+{
+       /*
+        * Number of ticks needed to cover the startup time of the ADC
+        * as defined in the electrical characteristics of the board,
+        * divided by 8. The formula thus is :
+        *   Startup Time = (ticks + 1) * 8 / ADC Clock
+        */
+       return round_up((startup_time * adc_clk_khz / 1000) - 1, 8) / 8;
+}
+
+static u32 calc_startup_ticks_9x5(u8 startup_time, u32 adc_clk_khz)
+{
+       /*
+        * For sama5d3x and at91sam9x5, the formula changes to:
+        * Startup Time = <lookup_table_value> / ADC Clock
+        */
+       const int startup_lookup[] = {
+               0  , 8  , 16 , 24 ,
+               64 , 80 , 96 , 112,
+               512, 576, 640, 704,
+               768, 832, 896, 960
+               };
+       int i, size = ARRAY_SIZE(startup_lookup);
+       unsigned int ticks;
+
+       ticks = startup_time * adc_clk_khz / 1000;
+       for (i = 0; i < size; i++)
+               if (ticks < startup_lookup[i])
+                       break;
+
+       ticks = i;
+       if (ticks == size)
+               /* Reach the end of lookup table */
+               ticks = size - 1;
+
+       return ticks;
+}
+
 static const struct of_device_id at91_adc_dt_ids[];
 
+static int at91_adc_probe_dt_ts(struct device_node *node,
+       struct at91_adc_state *st, struct device *dev)
+{
+       int ret;
+       u32 prop;
+
+       ret = of_property_read_u32(node, "atmel,adc-ts-wires", &prop);
+       if (ret) {
+               dev_info(dev, "ADC Touch screen is disabled.\n");
+               return 0;
+       }
+
+       switch (prop) {
+       case 4:
+       case 5:
+               st->touchscreen_type = prop;
+               break;
+       default:
+               dev_err(dev, "Unsupported number of touchscreen wires (%d). Should be 4 or 5.\n", prop);
+               return -EINVAL;
+       }
+
+       prop = 0;
+       of_property_read_u32(node, "atmel,adc-ts-pressure-threshold", &prop);
+       st->ts_pressure_threshold = prop;
+       if (st->ts_pressure_threshold) {
+               return 0;
+       } else {
+               dev_err(dev, "Invalid pressure threshold for the touchscreen\n");
+               return -EINVAL;
+       }
+}
+
 static int at91_adc_probe_dt(struct at91_adc_state *st,
                             struct platform_device *pdev)
 {
@@ -460,13 +688,6 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
        }
        st->channels_mask = prop;
 
-       if (of_property_read_u32(node, "atmel,adc-num-channels", &prop)) {
-               dev_err(&idev->dev, "Missing adc-num-channels property in the DT.\n");
-               ret = -EINVAL;
-               goto error_ret;
-       }
-       st->num_channels = prop;
-
        st->sleep_mode = of_property_read_bool(node, "atmel,adc-sleep-mode");
 
        if (of_property_read_u32(node, "atmel,adc-startup-time", &prop)) {
@@ -492,6 +713,7 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
                goto error_ret;
 
        st->registers = &st->caps->registers;
+       st->num_channels = st->caps->num_channels;
        st->trigger_number = of_get_child_count(node);
        st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number *
                                        sizeof(struct at91_adc_trigger),
@@ -523,6 +745,12 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
                i++;
        }
 
+       /* Check if touchscreen is supported. */
+       if (st->caps->has_ts)
+               return at91_adc_probe_dt_ts(node, st, &idev->dev);
+       else
+               dev_info(&idev->dev, "not support touchscreen in the adc compatible string.\n");
+
        return 0;
 
 error_ret:
@@ -554,6 +782,114 @@ static const struct iio_info at91_adc_info = {
        .read_raw = &at91_adc_read_raw,
 };
 
+/* Touchscreen related functions */
+static int atmel_ts_open(struct input_dev *dev)
+{
+       struct at91_adc_state *st = input_get_drvdata(dev);
+
+       at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN);
+       return 0;
+}
+
+static void atmel_ts_close(struct input_dev *dev)
+{
+       struct at91_adc_state *st = input_get_drvdata(dev);
+
+       at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN);
+}
+
+static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz)
+{
+       u32 reg = 0, pendbc;
+       int i = 0;
+
+       if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE)
+               reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS;
+       else
+               reg = AT91_ADC_TSMR_TSMODE_5WIRE;
+
+       /* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid
+        * pen detect noise.
+        * The formula is : Pen Detect Debounce Time = (2 ^ pendbc) / ADCClock
+        */
+       pendbc = round_up(TOUCH_PEN_DETECT_DEBOUNCE_US * adc_clk_khz / 1000, 1);
+
+       while (pendbc >> ++i)
+               ;       /* Empty! Find the shift offset */
+       if (abs(pendbc - (1 << i)) < abs(pendbc - (1 << (i - 1))))
+               pendbc = i;
+       else
+               pendbc = i - 1;
+
+       if (st->caps->has_tsmr) {
+               reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average)
+                               & AT91_ADC_TSMR_TSAV;
+               reg |= AT91_ADC_TSMR_PENDBC_(pendbc) & AT91_ADC_TSMR_PENDBC;
+               reg |= AT91_ADC_TSMR_NOTSDMA;
+               reg |= AT91_ADC_TSMR_PENDET_ENA;
+               reg |= 0x03 << 8;       /* TSFREQ, need bigger than TSAV */
+
+               at91_adc_writel(st, AT91_ADC_TSMR, reg);
+       } else {
+               /* TODO: for 9g45 which has no TSMR */
+       }
+
+       /* Change adc internal resistor value for better pen detection,
+        * default value is 100 kOhm.
+        * 0 = 200 kOhm, 1 = 150 kOhm, 2 = 100 kOhm, 3 = 50 kOhm
+        * option only available on ES2 and higher
+        */
+       at91_adc_writel(st, AT91_ADC_ACR, st->caps->ts_pen_detect_sensitivity
+                       & AT91_ADC_ACR_PENDETSENS);
+
+       /* Sample Peroid Time = (TRGPER + 1) / ADCClock */
+       st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US *
+                       adc_clk_khz / 1000) - 1, 1);
+
+       return 0;
+}
+
+static int at91_ts_register(struct at91_adc_state *st,
+               struct platform_device *pdev)
+{
+       struct input_dev *input;
+       struct iio_dev *idev = iio_priv_to_dev(st);
+       int ret;
+
+       input = input_allocate_device();
+       if (!input) {
+               dev_err(&idev->dev, "Failed to allocate TS device!\n");
+               return -ENOMEM;
+       }
+
+       input->name = DRIVER_NAME;
+       input->id.bustype = BUS_HOST;
+       input->dev.parent = &pdev->dev;
+       input->open = atmel_ts_open;
+       input->close = atmel_ts_close;
+
+       __set_bit(EV_ABS, input->evbit);
+       __set_bit(EV_KEY, input->evbit);
+       __set_bit(BTN_TOUCH, input->keybit);
+       input_set_abs_params(input, ABS_X, 0, (1 << MAX_POS_BITS) - 1, 0, 0);
+       input_set_abs_params(input, ABS_Y, 0, (1 << MAX_POS_BITS) - 1, 0, 0);
+       input_set_abs_params(input, ABS_PRESSURE, 0, 0xffffff, 0, 0);
+
+       st->ts_input = input;
+       input_set_drvdata(input, st);
+
+       ret = input_register_device(input);
+       if (ret)
+               input_free_device(st->ts_input);
+
+       return ret;
+}
+
+static void at91_ts_unregister(struct at91_adc_state *st)
+{
+       input_unregister_device(st->ts_input);
+}
+
 static int at91_adc_probe(struct platform_device *pdev)
 {
        unsigned int prsc, mstrclk, ticks, adc_clk, adc_clk_khz, shtim;
@@ -605,7 +941,7 @@ static int at91_adc_probe(struct platform_device *pdev)
        at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_SWRST);
        at91_adc_writel(st, AT91_ADC_IDR, 0xFFFFFFFF);
        ret = request_irq(st->irq,
-                         at91_adc_eoc_trigger,
+                         at91_adc_interrupt,
                          0,
                          pdev->dev.driver->name,
                          idev);
@@ -650,6 +986,10 @@ static int at91_adc_probe(struct platform_device *pdev)
        mstrclk = clk_get_rate(st->clk);
        adc_clk = clk_get_rate(st->adc_clk);
        adc_clk_khz = adc_clk / 1000;
+
+       dev_dbg(&pdev->dev, "Master clock is set as: %d Hz, adc_clk should set as: %d Hz\n",
+               mstrclk, adc_clk);
+
        prsc = (mstrclk / (2 * adc_clk)) - 1;
 
        if (!st->startup_time) {
@@ -657,14 +997,8 @@ static int at91_adc_probe(struct platform_device *pdev)
                ret = -EINVAL;
                goto error_disable_adc_clk;
        }
+       ticks = (*st->caps->calc_startup_ticks)(st->startup_time, adc_clk_khz);
 
-       /*
-        * Number of ticks needed to cover the startup time of the ADC as
-        * defined in the electrical characteristics of the board, divided by 8.
-        * The formula thus is : Startup Time = (ticks + 1) * 8 / ADC Clock
-        */
-       ticks = round_up((st->startup_time * adc_clk_khz /
-                         1000) - 1, 8) / 8;
        /*
         * a minimal Sample and Hold Time is necessary for the ADC to guarantee
         * the best converted final value between two channels selection
@@ -692,30 +1026,52 @@ static int at91_adc_probe(struct platform_device *pdev)
        init_waitqueue_head(&st->wq_data_avail);
        mutex_init(&st->lock);
 
-       ret = at91_adc_buffer_init(idev);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Couldn't initialize the buffer.\n");
-               goto error_disable_adc_clk;
-       }
+       /*
+        * Since touch screen will set trigger register as period trigger. So
+        * when touch screen is enabled, then we have to disable hardware
+        * trigger for classic adc.
+        */
+       if (!st->touchscreen_type) {
+               ret = at91_adc_buffer_init(idev);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "Couldn't initialize the buffer.\n");
+                       goto error_disable_adc_clk;
+               }
 
-       ret = at91_adc_trigger_init(idev);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Couldn't setup the triggers.\n");
-               goto error_unregister_buffer;
+               ret = at91_adc_trigger_init(idev);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "Couldn't setup the triggers.\n");
+                       at91_adc_buffer_remove(idev);
+                       goto error_disable_adc_clk;
+               }
+       } else {
+               if (!st->caps->has_tsmr) {
+                       dev_err(&pdev->dev, "We don't support non-TSMR adc\n");
+                       goto error_disable_adc_clk;
+               }
+
+               ret = at91_ts_register(st, pdev);
+               if (ret)
+                       goto error_disable_adc_clk;
+
+               at91_ts_hw_init(st, adc_clk_khz);
        }
 
        ret = iio_device_register(idev);
        if (ret < 0) {
                dev_err(&pdev->dev, "Couldn't register the device.\n");
-               goto error_remove_triggers;
+               goto error_iio_device_register;
        }
 
        return 0;
 
-error_remove_triggers:
-       at91_adc_trigger_remove(idev);
-error_unregister_buffer:
-       at91_adc_buffer_remove(idev);
+error_iio_device_register:
+       if (!st->touchscreen_type) {
+               at91_adc_trigger_remove(idev);
+               at91_adc_buffer_remove(idev);
+       } else {
+               at91_ts_unregister(st);
+       }
 error_disable_adc_clk:
        clk_disable_unprepare(st->adc_clk);
 error_disable_clk:
@@ -731,8 +1087,12 @@ static int at91_adc_remove(struct platform_device *pdev)
        struct at91_adc_state *st = iio_priv(idev);
 
        iio_device_unregister(idev);
-       at91_adc_trigger_remove(idev);
-       at91_adc_buffer_remove(idev);
+       if (!st->touchscreen_type) {
+               at91_adc_trigger_remove(idev);
+               at91_adc_buffer_remove(idev);
+       } else {
+               at91_ts_unregister(st);
+       }
        clk_disable_unprepare(st->adc_clk);
        clk_disable_unprepare(st->clk);
        free_irq(st->irq, idev);
@@ -742,6 +1102,8 @@ static int at91_adc_remove(struct platform_device *pdev)
 
 #ifdef CONFIG_OF
 static struct at91_adc_caps at91sam9260_caps = {
+       .calc_startup_ticks = calc_startup_ticks_9260,
+       .num_channels = 4,
        .registers = {
                .channel_base = AT91_ADC_CHR(0),
                .drdy_mask = AT91_ADC_DRDY,
@@ -753,6 +1115,9 @@ static struct at91_adc_caps at91sam9260_caps = {
 };
 
 static struct at91_adc_caps at91sam9g45_caps = {
+       .has_ts = true,
+       .calc_startup_ticks = calc_startup_ticks_9260,  /* same as 9260 */
+       .num_channels = 8,
        .registers = {
                .channel_base = AT91_ADC_CHR(0),
                .drdy_mask = AT91_ADC_DRDY,
@@ -764,6 +1129,12 @@ static struct at91_adc_caps at91sam9g45_caps = {
 };
 
 static struct at91_adc_caps at91sam9x5_caps = {
+       .has_ts = true,
+       .has_tsmr = true,
+       .ts_filter_average = 3,
+       .ts_pen_detect_sensitivity = 2,
+       .calc_startup_ticks = calc_startup_ticks_9x5,
+       .num_channels = 12,
        .registers = {
                .channel_base = AT91_ADC_CDR0_9X5,
                .drdy_mask = AT91_ADC_SR_DRDY_9X5,
@@ -788,7 +1159,7 @@ static struct platform_driver at91_adc_driver = {
        .probe = at91_adc_probe,
        .remove = at91_adc_remove,
        .driver = {
-                  .name = "at91_adc",
+                  .name = DRIVER_NAME,
                   .of_match_table = of_match_ptr(at91_adc_dt_ids),
        },
 };
index 4fb35d1d74943b72a77e9a5affe4f8f751382b22..cc07b3765fe01ff7a1be463bc0778b413e9d80d6 100644 (file)
@@ -397,7 +397,6 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
 {
        struct max1363_state *st = iio_priv(indio_dev);
        int ret;
-       unsigned long scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_RAW:
@@ -406,10 +405,9 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
                        return ret;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = st->vref_uv >> st->chip_info->bits;
-               *val = scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->vref_uv / 1000;
+               *val2 = st->chip_info->bits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        default:
                return -EINVAL;
        }
@@ -424,11 +422,21 @@ static const enum max1363_modes max1363_mode_list[] = {
        d0m1to2m3, d1m0to3m2,
 };
 
-#define MAX1363_EV_M                                           \
-       (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)      \
-        | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+static const struct iio_event_spec max1363_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),
+       },
+};
 
-#define MAX1363_CHAN_U(num, addr, si, bits, evmask)                    \
+#define MAX1363_CHAN_U(num, addr, si, bits, ev_spec, num_ev_spec)      \
        {                                                               \
                .type = IIO_VOLTAGE,                                    \
                .indexed = 1,                                           \
@@ -444,11 +452,12 @@ static const enum max1363_modes max1363_mode_list[] = {
                        .endianness = IIO_BE,                           \
                },                                                      \
                .scan_index = si,                                       \
-               .event_mask = evmask,                                   \
+               .event_spec = ev_spec,                                  \
+               .num_event_specs = num_ev_spec,                         \
        }
 
 /* bipolar channel */
-#define MAX1363_CHAN_B(num, num2, addr, si, bits, evmask)              \
+#define MAX1363_CHAN_B(num, num2, addr, si, bits, ev_spec, num_ev_spec)        \
        {                                                               \
                .type = IIO_VOLTAGE,                                    \
                .differential = 1,                                      \
@@ -466,28 +475,32 @@ static const enum max1363_modes max1363_mode_list[] = {
                        .endianness = IIO_BE,                           \
                },                                                      \
                .scan_index = si,                                       \
-               .event_mask = evmask,                                   \
+               .event_spec = ev_spec,                                  \
+               .num_event_specs = num_ev_spec,                         \
        }
 
-#define MAX1363_4X_CHANS(bits, em) {                   \
-       MAX1363_CHAN_U(0, _s0, 0, bits, em),            \
-       MAX1363_CHAN_U(1, _s1, 1, bits, em),            \
-       MAX1363_CHAN_U(2, _s2, 2, bits, em),            \
-       MAX1363_CHAN_U(3, _s3, 3, bits, em),            \
-       MAX1363_CHAN_B(0, 1, d0m1, 4, bits, em),        \
-       MAX1363_CHAN_B(2, 3, d2m3, 5, bits, em),        \
-       MAX1363_CHAN_B(1, 0, d1m0, 6, bits, em),        \
-       MAX1363_CHAN_B(3, 2, d3m2, 7, bits, em),        \
-       IIO_CHAN_SOFT_TIMESTAMP(8)                      \
+#define MAX1363_4X_CHANS(bits, ev_spec, num_ev_spec) {                 \
+       MAX1363_CHAN_U(0, _s0, 0, bits, ev_spec, num_ev_spec),          \
+       MAX1363_CHAN_U(1, _s1, 1, bits, ev_spec, num_ev_spec),          \
+       MAX1363_CHAN_U(2, _s2, 2, bits, ev_spec, num_ev_spec),          \
+       MAX1363_CHAN_U(3, _s3, 3, bits, ev_spec, num_ev_spec),          \
+       MAX1363_CHAN_B(0, 1, d0m1, 4, bits, ev_spec, num_ev_spec),      \
+       MAX1363_CHAN_B(2, 3, d2m3, 5, bits, ev_spec, num_ev_spec),      \
+       MAX1363_CHAN_B(1, 0, d1m0, 6, bits, ev_spec, num_ev_spec),      \
+       MAX1363_CHAN_B(3, 2, d3m2, 7, bits, ev_spec, num_ev_spec),      \
+       IIO_CHAN_SOFT_TIMESTAMP(8)                                      \
        }
 
-static const struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8, 0);
-static const struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10, 0);
-static const struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12, 0);
+static const struct iio_chan_spec max1036_channels[] =
+       MAX1363_4X_CHANS(8, NULL, 0);
+static const struct iio_chan_spec max1136_channels[] =
+       MAX1363_4X_CHANS(10, NULL, 0);
+static const struct iio_chan_spec max1236_channels[] =
+       MAX1363_4X_CHANS(12, NULL, 0);
 static const struct iio_chan_spec max1361_channels[] =
-       MAX1363_4X_CHANS(10, MAX1363_EV_M);
+       MAX1363_4X_CHANS(10, max1363_events, ARRAY_SIZE(max1363_events));
 static const struct iio_chan_spec max1363_channels[] =
-       MAX1363_4X_CHANS(12, MAX1363_EV_M);
+       MAX1363_4X_CHANS(12, max1363_events, ARRAY_SIZE(max1363_events));
 
 /* Applies to max1236, max1237 */
 static const enum max1363_modes max1236_mode_list[] = {
@@ -511,32 +524,32 @@ static const enum max1363_modes max1238_mode_list[] = {
        d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10,
 };
 
-#define MAX1363_12X_CHANS(bits) {                      \
-       MAX1363_CHAN_U(0, _s0, 0, bits, 0),             \
-       MAX1363_CHAN_U(1, _s1, 1, bits, 0),             \
-       MAX1363_CHAN_U(2, _s2, 2, bits, 0),             \
-       MAX1363_CHAN_U(3, _s3, 3, bits, 0),             \
-       MAX1363_CHAN_U(4, _s4, 4, bits, 0),             \
-       MAX1363_CHAN_U(5, _s5, 5, bits, 0),             \
-       MAX1363_CHAN_U(6, _s6, 6, bits, 0),             \
-       MAX1363_CHAN_U(7, _s7, 7, bits, 0),             \
-       MAX1363_CHAN_U(8, _s8, 8, bits, 0),             \
-       MAX1363_CHAN_U(9, _s9, 9, bits, 0),             \
-       MAX1363_CHAN_U(10, _s10, 10, bits, 0),          \
-       MAX1363_CHAN_U(11, _s11, 11, bits, 0),          \
-       MAX1363_CHAN_B(0, 1, d0m1, 12, bits, 0),        \
-       MAX1363_CHAN_B(2, 3, d2m3, 13, bits, 0),        \
-       MAX1363_CHAN_B(4, 5, d4m5, 14, bits, 0),        \
-       MAX1363_CHAN_B(6, 7, d6m7, 15, bits, 0),        \
-       MAX1363_CHAN_B(8, 9, d8m9, 16, bits, 0),        \
-       MAX1363_CHAN_B(10, 11, d10m11, 17, bits, 0),    \
-       MAX1363_CHAN_B(1, 0, d1m0, 18, bits, 0),        \
-       MAX1363_CHAN_B(3, 2, d3m2, 19, bits, 0),        \
-       MAX1363_CHAN_B(5, 4, d5m4, 20, bits, 0),        \
-       MAX1363_CHAN_B(7, 6, d7m6, 21, bits, 0),        \
-       MAX1363_CHAN_B(9, 8, d9m8, 22, bits, 0),        \
-       MAX1363_CHAN_B(11, 10, d11m10, 23, bits, 0),    \
-       IIO_CHAN_SOFT_TIMESTAMP(24)                     \
+#define MAX1363_12X_CHANS(bits) {                              \
+       MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),               \
+       MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),               \
+       MAX1363_CHAN_U(2, _s2, 2, bits, NULL, 0),               \
+       MAX1363_CHAN_U(3, _s3, 3, bits, NULL, 0),               \
+       MAX1363_CHAN_U(4, _s4, 4, bits, NULL, 0),               \
+       MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0),               \
+       MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0),               \
+       MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0),               \
+       MAX1363_CHAN_U(8, _s8, 8, bits, NULL, 0),               \
+       MAX1363_CHAN_U(9, _s9, 9, bits, NULL, 0),               \
+       MAX1363_CHAN_U(10, _s10, 10, bits, NULL, 0),            \
+       MAX1363_CHAN_U(11, _s11, 11, bits, NULL, 0),            \
+       MAX1363_CHAN_B(0, 1, d0m1, 12, bits, NULL, 0),          \
+       MAX1363_CHAN_B(2, 3, d2m3, 13, bits, NULL, 0),          \
+       MAX1363_CHAN_B(4, 5, d4m5, 14, bits, NULL, 0),          \
+       MAX1363_CHAN_B(6, 7, d6m7, 15, bits, NULL, 0),          \
+       MAX1363_CHAN_B(8, 9, d8m9, 16, bits, NULL, 0),          \
+       MAX1363_CHAN_B(10, 11, d10m11, 17, bits, NULL, 0),      \
+       MAX1363_CHAN_B(1, 0, d1m0, 18, bits, NULL, 0),          \
+       MAX1363_CHAN_B(3, 2, d3m2, 19, bits, NULL, 0),          \
+       MAX1363_CHAN_B(5, 4, d5m4, 20, bits, NULL, 0),          \
+       MAX1363_CHAN_B(7, 6, d7m6, 21, bits, NULL, 0),          \
+       MAX1363_CHAN_B(9, 8, d9m8, 22, bits, NULL, 0),          \
+       MAX1363_CHAN_B(11, 10, d11m10, 23, bits, NULL, 0),      \
+       IIO_CHAN_SOFT_TIMESTAMP(24)                             \
        }
 static const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8);
 static const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10);
@@ -561,22 +574,22 @@ static const enum max1363_modes max11608_mode_list[] = {
 };
 
 #define MAX1363_8X_CHANS(bits) {                       \
-       MAX1363_CHAN_U(0, _s0, 0, bits, 0),             \
-       MAX1363_CHAN_U(1, _s1, 1, bits, 0),             \
-       MAX1363_CHAN_U(2, _s2, 2, bits, 0),             \
-       MAX1363_CHAN_U(3, _s3, 3, bits, 0),             \
-       MAX1363_CHAN_U(4, _s4, 4, bits, 0),             \
-       MAX1363_CHAN_U(5, _s5, 5, bits, 0),             \
-       MAX1363_CHAN_U(6, _s6, 6, bits, 0),             \
-       MAX1363_CHAN_U(7, _s7, 7, bits, 0),             \
-       MAX1363_CHAN_B(0, 1, d0m1, 8, bits, 0), \
-       MAX1363_CHAN_B(2, 3, d2m3, 9, bits, 0), \
-       MAX1363_CHAN_B(4, 5, d4m5, 10, bits, 0),        \
-       MAX1363_CHAN_B(6, 7, d6m7, 11, bits, 0),        \
-       MAX1363_CHAN_B(1, 0, d1m0, 12, bits, 0),        \
-       MAX1363_CHAN_B(3, 2, d3m2, 13, bits, 0),        \
-       MAX1363_CHAN_B(5, 4, d5m4, 14, bits, 0),        \
-       MAX1363_CHAN_B(7, 6, d7m6, 15, bits, 0),        \
+       MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),       \
+       MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),       \
+       MAX1363_CHAN_U(2, _s2, 2, bits, NULL, 0),       \
+       MAX1363_CHAN_U(3, _s3, 3, bits, NULL, 0),       \
+       MAX1363_CHAN_U(4, _s4, 4, bits, NULL, 0),       \
+       MAX1363_CHAN_U(5, _s5, 5, bits, NULL, 0),       \
+       MAX1363_CHAN_U(6, _s6, 6, bits, NULL, 0),       \
+       MAX1363_CHAN_U(7, _s7, 7, bits, NULL, 0),       \
+       MAX1363_CHAN_B(0, 1, d0m1, 8, bits, NULL, 0),   \
+       MAX1363_CHAN_B(2, 3, d2m3, 9, bits, NULL, 0),   \
+       MAX1363_CHAN_B(4, 5, d4m5, 10, bits, NULL, 0),  \
+       MAX1363_CHAN_B(6, 7, d6m7, 11, bits, NULL, 0),  \
+       MAX1363_CHAN_B(1, 0, d1m0, 12, bits, NULL, 0),  \
+       MAX1363_CHAN_B(3, 2, d3m2, 13, bits, NULL, 0),  \
+       MAX1363_CHAN_B(5, 4, d5m4, 14, bits, NULL, 0),  \
+       MAX1363_CHAN_B(7, 6, d7m6, 15, bits, NULL, 0),  \
        IIO_CHAN_SOFT_TIMESTAMP(16)                     \
 }
 static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8);
@@ -588,10 +601,10 @@ static const enum max1363_modes max11644_mode_list[] = {
 };
 
 #define MAX1363_2X_CHANS(bits) {                       \
-       MAX1363_CHAN_U(0, _s0, 0, bits, 0),             \
-       MAX1363_CHAN_U(1, _s1, 1, bits, 0),             \
-       MAX1363_CHAN_B(0, 1, d0m1, 2, bits, 0), \
-       MAX1363_CHAN_B(1, 0, d1m0, 3, bits, 0), \
+       MAX1363_CHAN_U(0, _s0, 0, bits, NULL, 0),       \
+       MAX1363_CHAN_U(1, _s1, 1, bits, NULL, 0),       \
+       MAX1363_CHAN_B(0, 1, d0m1, 2, bits, NULL, 0),   \
+       MAX1363_CHAN_B(1, 0, d1m0, 3, bits, NULL, 0),   \
        IIO_CHAN_SOFT_TIMESTAMP(4)                      \
        }
 
@@ -686,20 +699,22 @@ static IIO_CONST_ATTR(sampling_frequency_available,
                "133000 665000 33300 16600 8300 4200 2000 1000");
 
 static int max1363_read_thresh(struct iio_dev *indio_dev,
-                              u64 event_code,
-                              int *val)
+       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 max1363_state *st = iio_priv(indio_dev);
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
-               *val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)];
+       if (dir == IIO_EV_DIR_FALLING)
+               *val = st->thresh_low[chan->channel];
        else
-               *val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)];
-       return 0;
+               *val = st->thresh_high[chan->channel];
+       return IIO_VAL_INT;
 }
 
 static int max1363_write_thresh(struct iio_dev *indio_dev,
-                               u64 event_code,
-                               int val)
+       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 max1363_state *st = iio_priv(indio_dev);
        /* make it handle signed correctly as well */
@@ -714,13 +729,15 @@ static int max1363_write_thresh(struct iio_dev *indio_dev,
                break;
        }
 
-       switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+       switch (dir) {
        case IIO_EV_DIR_FALLING:
-               st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val;
+               st->thresh_low[chan->channel] = val;
                break;
        case IIO_EV_DIR_RISING:
-               st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val;
+               st->thresh_high[chan->channel] = val;
                break;
+       default:
+               return -EINVAL;
        }
 
        return 0;
@@ -765,14 +782,15 @@ static irqreturn_t max1363_event_handler(int irq, void *private)
 }
 
 static int max1363_read_event_config(struct iio_dev *indio_dev,
-                                    u64 event_code)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir)
 {
        struct max1363_state *st = iio_priv(indio_dev);
        int val;
-       int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+       int number = chan->channel;
 
        mutex_lock(&indio_dev->mlock);
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
+       if (dir == IIO_EV_DIR_FALLING)
                val = (1 << number) & st->mask_low;
        else
                val = (1 << number) & st->mask_high;
@@ -917,17 +935,17 @@ error_ret:
 }
 
 static int max1363_write_event_config(struct iio_dev *indio_dev,
-                                     u64 event_code,
-                                     int state)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, int state)
 {
        int ret = 0;
        struct max1363_state *st = iio_priv(indio_dev);
        u16 unifiedmask;
-       int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+       int number = chan->channel;
 
        mutex_lock(&indio_dev->mlock);
        unifiedmask = st->mask_low | st->mask_high;
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) {
+       if (dir == IIO_EV_DIR_FALLING) {
 
                if (state == 0)
                        st->mask_low &= ~(1 << number);
@@ -995,10 +1013,10 @@ static const struct iio_info max1238_info = {
 };
 
 static const struct iio_info max1363_info = {
-       .read_event_value = &max1363_read_thresh,
-       .write_event_value = &max1363_write_thresh,
-       .read_event_config = &max1363_read_event_config,
-       .write_event_config = &max1363_write_event_config,
+       .read_event_value_new = &max1363_read_thresh,
+       .write_event_value_new = &max1363_write_thresh,
+       .read_event_config_new = &max1363_read_event_config,
+       .write_event_config_new = &max1363_write_event_config,
        .read_raw = &max1363_read_raw,
        .update_scan_mode = &max1363_update_scan_mode,
        .driver_module = THIS_MODULE,
@@ -1436,7 +1454,6 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct max1363_state *st = iio_priv(indio_dev);
-       s64 time_ns;
        __u8 *rxbuf;
        int b_sent;
        size_t d_size;
@@ -1470,11 +1487,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
        if (b_sent < 0)
                goto done_free;
 
-       time_ns = iio_get_time_ns();
-
-       if (indio_dev->scan_timestamp)
-               memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
-       iio_push_to_buffers(indio_dev, rxbuf);
+       iio_push_to_buffers_with_timestamp(indio_dev, rxbuf, iio_get_time_ns());
 
 done_free:
        kfree(rxbuf);
@@ -1484,12 +1497,6 @@ done:
        return IRQ_HANDLED;
 }
 
-static const struct iio_buffer_setup_ops max1363_buffered_setup_ops = {
-       .postenable = &iio_triggered_buffer_postenable,
-       .preenable = &iio_sw_buffer_preenable,
-       .predisable = &iio_triggered_buffer_predisable,
-};
-
 static int max1363_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
@@ -1559,7 +1566,7 @@ static int max1363_probe(struct i2c_client *client,
                goto error_disable_reg;
 
        ret = iio_triggered_buffer_setup(indio_dev, NULL,
-               &max1363_trigger_handler, &max1363_buffered_setup_ops);
+               &max1363_trigger_handler, NULL);
        if (ret)
                goto error_disable_reg;
 
diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c
new file mode 100644 (file)
index 0000000..1294832
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * mcp3422.c - driver for the Microchip mcp3422/3/4 chip family
+ *
+ * Copyright (C) 2013, Angelo Compagnucci
+ * Author: Angelo Compagnucci <angelo.compagnucci@gmail.com>
+ *
+ * Datasheet: http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf
+ *
+ * This driver exports the value of analog input voltage to sysfs, the
+ * voltage unit is nV.
+ *
+ * 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.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/sysfs.h>
+#include <linux/of.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+/* Masks */
+#define MCP3422_CHANNEL_MASK   0x60
+#define MCP3422_PGA_MASK       0x03
+#define MCP3422_SRATE_MASK     0x0C
+#define MCP3422_SRATE_240      0x0
+#define MCP3422_SRATE_60       0x1
+#define MCP3422_SRATE_15       0x2
+#define MCP3422_SRATE_3        0x3
+#define MCP3422_PGA_1  0
+#define MCP3422_PGA_2  1
+#define MCP3422_PGA_4  2
+#define MCP3422_PGA_8  3
+#define MCP3422_CONT_SAMPLING  0x10
+
+#define MCP3422_CHANNEL(config)        (((config) & MCP3422_CHANNEL_MASK) >> 5)
+#define MCP3422_PGA(config)    ((config) & MCP3422_PGA_MASK)
+#define MCP3422_SAMPLE_RATE(config)    (((config) & MCP3422_SRATE_MASK) >> 2)
+
+#define MCP3422_CHANNEL_VALUE(value) (((value) << 5) & MCP3422_CHANNEL_MASK)
+#define MCP3422_PGA_VALUE(value) ((value) & MCP3422_PGA_MASK)
+#define MCP3422_SAMPLE_RATE_VALUE(value) ((value << 2) & MCP3422_SRATE_MASK)
+
+#define MCP3422_CHAN(_index) \
+       { \
+               .type = IIO_VOLTAGE, \
+               .indexed = 1, \
+               .channel = _index, \
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \
+                               | BIT(IIO_CHAN_INFO_SCALE), \
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
+       }
+
+/* LSB is in nV to eliminate floating point */
+static const u32 rates_to_lsb[] = {1000000, 250000, 62500, 15625};
+
+/*
+ *  scales calculated as:
+ *  rates_to_lsb[sample_rate] / (1 << pga);
+ *  pga is 1 for 0, 2
+ */
+
+static const int mcp3422_scales[4][4] = {
+       { 1000000, 250000, 62500, 15625 },
+       { 500000 , 125000, 31250, 7812 },
+       { 250000 , 62500 , 15625, 3906 },
+       { 125000 , 31250 , 7812 , 1953 } };
+
+/* Constant msleep times for data acquisitions */
+static const int mcp3422_read_times[4] = {
+       [MCP3422_SRATE_240] = 1000 / 240,
+       [MCP3422_SRATE_60] = 1000 / 60,
+       [MCP3422_SRATE_15] = 1000 / 15,
+       [MCP3422_SRATE_3] = 1000 / 3 };
+
+/* sample rates to integer conversion table */
+static const int mcp3422_sample_rates[4] = {
+       [MCP3422_SRATE_240] = 240,
+       [MCP3422_SRATE_60] = 60,
+       [MCP3422_SRATE_15] = 15,
+       [MCP3422_SRATE_3] = 3 };
+
+/* sample rates to sign extension table */
+static const int mcp3422_sign_extend[4] = {
+       [MCP3422_SRATE_240] = 12,
+       [MCP3422_SRATE_60] = 14,
+       [MCP3422_SRATE_15] = 16,
+       [MCP3422_SRATE_3] = 18 };
+
+/* Client data (each client gets its own) */
+struct mcp3422 {
+       struct i2c_client *i2c;
+       u8 config;
+       u8 pga[4];
+       struct mutex lock;
+};
+
+static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig)
+{
+       int ret;
+
+       mutex_lock(&adc->lock);
+
+       ret = i2c_master_send(adc->i2c, &newconfig, 1);
+       if (ret > 0) {
+               adc->config = newconfig;
+               ret = 0;
+       }
+
+       mutex_unlock(&adc->lock);
+
+       return ret;
+}
+
+static int mcp3422_read(struct mcp3422 *adc, int *value, u8 *config)
+{
+       int ret = 0;
+       u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
+       u8 buf[4] = {0, 0, 0, 0};
+       u32 temp;
+
+       if (sample_rate == MCP3422_SRATE_3) {
+               ret = i2c_master_recv(adc->i2c, buf, 4);
+               temp = buf[0] << 16 | buf[1] << 8 | buf[2];
+               *config = buf[3];
+       } else {
+               ret = i2c_master_recv(adc->i2c, buf, 3);
+               temp = buf[0] << 8 | buf[1];
+               *config = buf[2];
+       }
+
+       *value = sign_extend32(temp, mcp3422_sign_extend[sample_rate]);
+
+       return ret;
+}
+
+static int mcp3422_read_channel(struct mcp3422 *adc,
+                               struct iio_chan_spec const *channel, int *value)
+{
+       int ret;
+       u8 config;
+       u8 req_channel = channel->channel;
+
+       if (req_channel != MCP3422_CHANNEL(adc->config)) {
+               config = adc->config;
+               config &= ~MCP3422_CHANNEL_MASK;
+               config |= MCP3422_CHANNEL_VALUE(req_channel);
+               config &= ~MCP3422_PGA_MASK;
+               config |= MCP3422_PGA_VALUE(adc->pga[req_channel]);
+               ret = mcp3422_update_config(adc, config);
+               if (ret < 0)
+                       return ret;
+               msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]);
+       }
+
+       return mcp3422_read(adc, value, &config);
+}
+
+static int mcp3422_read_raw(struct iio_dev *iio,
+                       struct iio_chan_spec const *channel, int *val1,
+                       int *val2, long mask)
+{
+       struct mcp3422 *adc = iio_priv(iio);
+       int err;
+
+       u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
+       u8 pga           = MCP3422_PGA(adc->config);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               err = mcp3422_read_channel(adc, channel, val1);
+               if (err < 0)
+                       return -EINVAL;
+               return IIO_VAL_INT;
+
+       case IIO_CHAN_INFO_SCALE:
+
+               *val1 = 0;
+               *val2 = mcp3422_scales[sample_rate][pga];
+               return IIO_VAL_INT_PLUS_NANO;
+
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *val1 = mcp3422_sample_rates[MCP3422_SAMPLE_RATE(adc->config)];
+               return IIO_VAL_INT;
+
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int mcp3422_write_raw(struct iio_dev *iio,
+                       struct iio_chan_spec const *channel, int val1,
+                       int val2, long mask)
+{
+       struct mcp3422 *adc = iio_priv(iio);
+       u8 temp;
+       u8 config = adc->config;
+       u8 req_channel = channel->channel;
+       u8 sample_rate = MCP3422_SAMPLE_RATE(config);
+       u8 i;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_SCALE:
+               if (val1 != 0)
+                       return -EINVAL;
+
+               for (i = 0; i < ARRAY_SIZE(mcp3422_scales[0]); i++) {
+                       if (val2 == mcp3422_scales[sample_rate][i]) {
+                               adc->pga[req_channel] = i;
+
+                               config &= ~MCP3422_CHANNEL_MASK;
+                               config |= MCP3422_CHANNEL_VALUE(req_channel);
+                               config &= ~MCP3422_PGA_MASK;
+                               config |= MCP3422_PGA_VALUE(adc->pga[req_channel]);
+
+                               return mcp3422_update_config(adc, config);
+                       }
+               }
+               return -EINVAL;
+
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               switch (val1) {
+               case 240:
+                       temp = MCP3422_SRATE_240;
+                       break;
+               case 60:
+                       temp = MCP3422_SRATE_60;
+                       break;
+               case 15:
+                       temp = MCP3422_SRATE_15;
+                       break;
+               case 3:
+                       temp = MCP3422_SRATE_3;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               config &= ~MCP3422_CHANNEL_MASK;
+               config |= MCP3422_CHANNEL_VALUE(req_channel);
+               config &= ~MCP3422_SRATE_MASK;
+               config |= MCP3422_SAMPLE_RATE_VALUE(temp);
+
+               return mcp3422_update_config(adc, config);
+
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int mcp3422_write_raw_get_fmt(struct iio_dev *indio_dev,
+               struct iio_chan_spec const *chan, long mask)
+{
+       switch (mask) {
+       case IIO_CHAN_INFO_SCALE:
+               return IIO_VAL_INT_PLUS_NANO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
+}
+
+static ssize_t mcp3422_show_scales(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev));
+       u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
+
+       return sprintf(buf, "0.%09u 0.%09u 0.%09u 0.%09u\n",
+               mcp3422_scales[sample_rate][0],
+               mcp3422_scales[sample_rate][1],
+               mcp3422_scales[sample_rate][2],
+               mcp3422_scales[sample_rate][3]);
+}
+
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("240 60 15 3");
+static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
+               mcp3422_show_scales, NULL, 0);
+
+static struct attribute *mcp3422_attributes[] = {
+       &iio_const_attr_sampling_frequency_available.dev_attr.attr,
+       &iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
+       NULL,
+};
+
+static const struct attribute_group mcp3422_attribute_group = {
+       .attrs = mcp3422_attributes,
+};
+
+static const struct iio_chan_spec mcp3422_channels[] = {
+       MCP3422_CHAN(0),
+       MCP3422_CHAN(1),
+};
+
+static const struct iio_chan_spec mcp3424_channels[] = {
+       MCP3422_CHAN(0),
+       MCP3422_CHAN(1),
+       MCP3422_CHAN(2),
+       MCP3422_CHAN(3),
+};
+
+static const struct iio_info mcp3422_info = {
+       .read_raw = mcp3422_read_raw,
+       .write_raw = mcp3422_write_raw,
+       .write_raw_get_fmt = mcp3422_write_raw_get_fmt,
+       .attrs = &mcp3422_attribute_group,
+       .driver_module = THIS_MODULE,
+};
+
+static int mcp3422_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct iio_dev *indio_dev;
+       struct mcp3422 *adc;
+       int err;
+       u8 config;
+
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+               return -ENODEV;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adc));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       adc = iio_priv(indio_dev);
+       adc->i2c = client;
+
+       mutex_init(&adc->lock);
+
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->name = dev_name(&client->dev);
+       indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->info = &mcp3422_info;
+
+       switch ((unsigned int)(id->driver_data)) {
+       case 2:
+       case 3:
+               indio_dev->channels = mcp3422_channels;
+               indio_dev->num_channels = ARRAY_SIZE(mcp3422_channels);
+               break;
+       case 4:
+               indio_dev->channels = mcp3424_channels;
+               indio_dev->num_channels = ARRAY_SIZE(mcp3424_channels);
+               break;
+       }
+
+       /* meaningful default configuration */
+       config = (MCP3422_CONT_SAMPLING
+               | MCP3422_CHANNEL_VALUE(1)
+               | MCP3422_PGA_VALUE(MCP3422_PGA_1)
+               | MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240));
+       mcp3422_update_config(adc, config);
+
+       err = iio_device_register(indio_dev);
+       if (err < 0)
+               return err;
+
+       i2c_set_clientdata(client, indio_dev);
+
+       return 0;
+}
+
+static int mcp3422_remove(struct i2c_client *client)
+{
+       iio_device_unregister(i2c_get_clientdata(client));
+       return 0;
+}
+
+static const struct i2c_device_id mcp3422_id[] = {
+       { "mcp3422", 2 },
+       { "mcp3423", 3 },
+       { "mcp3424", 4 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, mcp3422_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id mcp3422_of_match[] = {
+       { .compatible = "mcp3422" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, mcp3422_of_match);
+#endif
+
+static struct i2c_driver mcp3422_driver = {
+       .driver = {
+               .name = "mcp3422",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(mcp3422_of_match),
+       },
+       .probe = mcp3422_probe,
+       .remove = mcp3422_remove,
+       .id_table = mcp3422_id,
+};
+module_i2c_driver(mcp3422_driver);
+
+MODULE_AUTHOR("Angelo Compagnucci <angelo.compagnucci@gmail.com>");
+MODULE_DESCRIPTION("Microchip mcp3422/3/4 driver");
+MODULE_LICENSE("GPL v2");
index bdf03468f3b8d3e73417c3ad8d841b376d482a33..adff9cbbcbc4cc53260ab0c835d7a3a4cf36a9f3 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/wait.h>
 #include <linux/log2.h>
+#include <linux/of.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
index ee5f72bffe5a8f993276d480ba5a65e685ada659..b3a82b4d1a7587b586077982f27856dcfdb7dee5 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
+#include <linux/of.h>
 
 #include <linux/iio/iio.h>
 #include <linux/regulator/consumer.h>
index a952538a1a8b5be11078744f1463d45067dee567..ef54d8a588d20d7fead50dc0187dc3c4a0fb3baa 100644 (file)
 #include <linux/iio/driver.h>
 
 #include <linux/mfd/ti_am335x_tscadc.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/kfifo_buf.h>
 
 struct tiadc_device {
        struct ti_tscadc_dev *mfd_tscadc;
        int channels;
        u8 channel_line[8];
        u8 channel_step[8];
+       int buffer_en_ch_steps;
+       u16 data[8];
 };
 
 static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
@@ -56,8 +60,14 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
        return step_en;
 }
 
-static void tiadc_step_config(struct tiadc_device *adc_dev)
+static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan)
 {
+       return 1 << adc_dev->channel_step[chan];
+}
+
+static void tiadc_step_config(struct iio_dev *indio_dev)
+{
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
        unsigned int stepconfig;
        int i, steps;
 
@@ -72,7 +82,11 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
         */
 
        steps = TOTAL_STEPS - adc_dev->channels;
-       stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
+       if (iio_buffer_enabled(indio_dev))
+               stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1
+                                       | STEPCONFIG_MODE_SWCNT;
+       else
+               stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
 
        for (i = 0; i < adc_dev->channels; i++) {
                int chan;
@@ -85,9 +99,175 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
                adc_dev->channel_step[i] = steps;
                steps++;
        }
+}
+
+static irqreturn_t tiadc_irq_h(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+       unsigned int status, config;
+       status = tiadc_readl(adc_dev, REG_IRQSTATUS);
+
+       /*
+        * ADC and touchscreen share the IRQ line.
+        * FIFO0 interrupts are used by TSC. Handle FIFO1 IRQs here only
+        */
+       if (status & IRQENB_FIFO1OVRRUN) {
+               /* FIFO Overrun. Clear flag. Disable/Enable ADC to recover */
+               config = tiadc_readl(adc_dev, REG_CTRL);
+               config &= ~(CNTRLREG_TSCSSENB);
+               tiadc_writel(adc_dev, REG_CTRL, config);
+               tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1OVRRUN
+                               | IRQENB_FIFO1UNDRFLW | IRQENB_FIFO1THRES);
+               tiadc_writel(adc_dev, REG_CTRL, (config | CNTRLREG_TSCSSENB));
+               return IRQ_HANDLED;
+       } else if (status & IRQENB_FIFO1THRES) {
+               /* Disable irq and wake worker thread */
+               tiadc_writel(adc_dev, REG_IRQCLR, IRQENB_FIFO1THRES);
+               return IRQ_WAKE_THREAD;
+       }
+
+       return IRQ_NONE;
+}
+
+static irqreturn_t tiadc_worker_h(int irq, void *private)
+{
+       struct iio_dev *indio_dev = private;
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+       int i, k, fifo1count, read;
+       u16 *data = adc_dev->data;
+
+       fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+       for (k = 0; k < fifo1count; k = k + i) {
+               for (i = 0; i < (indio_dev->scan_bytes)/2; i++) {
+                       read = tiadc_readl(adc_dev, REG_FIFO1);
+                       data[i] = read & FIFOREAD_DATA_MASK;
+               }
+               iio_push_to_buffers(indio_dev, (u8 *) data);
+       }
+
+       tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1THRES);
+       tiadc_writel(adc_dev, REG_IRQENABLE, IRQENB_FIFO1THRES);
 
+       return IRQ_HANDLED;
 }
 
+static int tiadc_buffer_preenable(struct iio_dev *indio_dev)
+{
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+       int i, fifo1count, read;
+
+       tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
+                               IRQENB_FIFO1OVRRUN |
+                               IRQENB_FIFO1UNDRFLW));
+
+       /* Flush FIFO. Needed in corner cases in simultaneous tsc/adc use */
+       fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+       for (i = 0; i < fifo1count; i++)
+               read = tiadc_readl(adc_dev, REG_FIFO1);
+
+       return 0;
+}
+
+static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
+{
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+       struct iio_buffer *buffer = indio_dev->buffer;
+       unsigned int enb = 0;
+       u8 bit;
+
+       tiadc_step_config(indio_dev);
+       for_each_set_bit(bit, buffer->scan_mask, adc_dev->channels)
+               enb |= (get_adc_step_bit(adc_dev, bit) << 1);
+       adc_dev->buffer_en_ch_steps = enb;
+
+       am335x_tsc_se_set(adc_dev->mfd_tscadc, enb);
+
+       tiadc_writel(adc_dev,  REG_IRQSTATUS, IRQENB_FIFO1THRES
+                               | IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW);
+       tiadc_writel(adc_dev,  REG_IRQENABLE, IRQENB_FIFO1THRES
+                               | IRQENB_FIFO1OVRRUN);
+
+       return 0;
+}
+
+static int tiadc_buffer_predisable(struct iio_dev *indio_dev)
+{
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+       int fifo1count, i, read;
+
+       tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
+                               IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW));
+       am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps);
+
+       /* Flush FIFO of leftover data in the time it takes to disable adc */
+       fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
+       for (i = 0; i < fifo1count; i++)
+               read = tiadc_readl(adc_dev, REG_FIFO1);
+
+       return 0;
+}
+
+static int tiadc_buffer_postdisable(struct iio_dev *indio_dev)
+{
+       tiadc_step_config(indio_dev);
+
+       return 0;
+}
+
+static const struct iio_buffer_setup_ops tiadc_buffer_setup_ops = {
+       .preenable = &tiadc_buffer_preenable,
+       .postenable = &tiadc_buffer_postenable,
+       .predisable = &tiadc_buffer_predisable,
+       .postdisable = &tiadc_buffer_postdisable,
+};
+
+static int tiadc_iio_buffered_hardware_setup(struct iio_dev *indio_dev,
+       irqreturn_t (*pollfunc_bh)(int irq, void *p),
+       irqreturn_t (*pollfunc_th)(int irq, void *p),
+       int irq,
+       unsigned long flags,
+       const struct iio_buffer_setup_ops *setup_ops)
+{
+       int ret;
+
+       indio_dev->buffer = iio_kfifo_allocate(indio_dev);
+       if (!indio_dev->buffer)
+               return -ENOMEM;
+
+       ret = request_threaded_irq(irq, pollfunc_th, pollfunc_bh,
+                               flags, indio_dev->name, indio_dev);
+       if (ret)
+               goto error_kfifo_free;
+
+       indio_dev->setup_ops = setup_ops;
+       indio_dev->modes |= INDIO_BUFFER_HARDWARE;
+
+       ret = iio_buffer_register(indio_dev,
+                                 indio_dev->channels,
+                                 indio_dev->num_channels);
+       if (ret)
+               goto error_free_irq;
+
+       return 0;
+
+error_free_irq:
+       free_irq(irq, indio_dev);
+error_kfifo_free:
+       iio_kfifo_free(indio_dev->buffer);
+       return ret;
+}
+
+static void tiadc_iio_buffered_hardware_remove(struct iio_dev *indio_dev)
+{
+       struct tiadc_device *adc_dev = iio_priv(indio_dev);
+
+       free_irq(adc_dev->mfd_tscadc->irq, indio_dev);
+       iio_kfifo_free(indio_dev->buffer);
+       iio_buffer_unregister(indio_dev);
+}
+
+
 static const char * const chan_name_ain[] = {
        "AIN0",
        "AIN1",
@@ -120,9 +300,10 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
                chan->channel = adc_dev->channel_line[i];
                chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
                chan->datasheet_name = chan_name_ain[chan->channel];
+               chan->scan_index = i;
                chan->scan_type.sign = 'u';
                chan->scan_type.realbits = 12;
-               chan->scan_type.storagebits = 32;
+               chan->scan_type.storagebits = 16;
        }
 
        indio_dev->channels = chan_array;
@@ -142,11 +323,14 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
        struct tiadc_device *adc_dev = iio_priv(indio_dev);
        int i, map_val;
        unsigned int fifo1count, read, stepid;
-       u32 step = UINT_MAX;
        bool found = false;
        u32 step_en;
        unsigned long timeout = jiffies + usecs_to_jiffies
                                (IDLE_TIMEOUT * adc_dev->channels);
+
+       if (iio_buffer_enabled(indio_dev))
+               return -EBUSY;
+
        step_en = get_adc_step_mask(adc_dev);
        am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
 
@@ -168,15 +352,6 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
         * Hence we need to flush out this data.
         */
 
-       for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
-               if (chan->channel == adc_dev->channel_line[i]) {
-                       step = adc_dev->channel_step[i];
-                       break;
-               }
-       }
-       if (WARN_ON_ONCE(step == UINT_MAX))
-               return -EINVAL;
-
        fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
        for (i = 0; i < fifo1count; i++) {
                read = tiadc_readl(adc_dev, REG_FIFO1);
@@ -186,7 +361,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
                if (stepid == map_val) {
                        read = read & FIFOREAD_DATA_MASK;
                        found = true;
-                       *val = read;
+                       *val = (u16) read;
                }
        }
 
@@ -237,20 +412,33 @@ static int tiadc_probe(struct platform_device *pdev)
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &tiadc_info;
 
-       tiadc_step_config(adc_dev);
+       tiadc_step_config(indio_dev);
+       tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD);
 
        err = tiadc_channel_init(indio_dev, adc_dev->channels);
        if (err < 0)
                return err;
 
-       err = iio_device_register(indio_dev);
+       err = tiadc_iio_buffered_hardware_setup(indio_dev,
+               &tiadc_worker_h,
+               &tiadc_irq_h,
+               adc_dev->mfd_tscadc->irq,
+               IRQF_SHARED,
+               &tiadc_buffer_setup_ops);
+
        if (err)
                goto err_free_channels;
 
+       err = iio_device_register(indio_dev);
+       if (err)
+               goto err_buffer_unregister;
+
        platform_set_drvdata(pdev, indio_dev);
 
        return 0;
 
+err_buffer_unregister:
+       tiadc_iio_buffered_hardware_remove(indio_dev);
 err_free_channels:
        tiadc_channels_remove(indio_dev);
        return err;
@@ -263,6 +451,7 @@ static int tiadc_remove(struct platform_device *pdev)
        u32 step_en;
 
        iio_device_unregister(indio_dev);
+       tiadc_iio_buffered_hardware_remove(indio_dev);
        tiadc_channels_remove(indio_dev);
 
        step_en = get_adc_step_mask(adc_dev);
@@ -301,7 +490,7 @@ static int tiadc_resume(struct device *dev)
        restore &= ~(CNTRLREG_POWERDOWN);
        tiadc_writel(adc_dev, REG_CTRL, restore);
 
-       tiadc_step_config(adc_dev);
+       tiadc_step_config(indio_dev);
 
        return 0;
 }
index 415f3c6efd7293087cc1d5fa9313e9de308e6245..2d9c6f8c06db999017576e50c6d3e789c0f3f584 100644 (file)
@@ -7,26 +7,36 @@
 
 struct iio_cb_buffer {
        struct iio_buffer buffer;
-       int (*cb)(u8 *data, void *private);
+       int (*cb)(const void *data, void *private);
        void *private;
        struct iio_channel *channels;
 };
 
-static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data)
+static struct iio_cb_buffer *buffer_to_cb_buffer(struct iio_buffer *buffer)
 {
-       struct iio_cb_buffer *cb_buff = container_of(buffer,
-                                                    struct iio_cb_buffer,
-                                                    buffer);
+       return container_of(buffer, struct iio_cb_buffer, buffer);
+}
 
+static int iio_buffer_cb_store_to(struct iio_buffer *buffer, const void *data)
+{
+       struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer);
        return cb_buff->cb(data, cb_buff->private);
 }
 
-static struct iio_buffer_access_funcs iio_cb_access = {
+static void iio_buffer_cb_release(struct iio_buffer *buffer)
+{
+       struct iio_cb_buffer *cb_buff = buffer_to_cb_buffer(buffer);
+       kfree(cb_buff->buffer.scan_mask);
+       kfree(cb_buff);
+}
+
+static const struct iio_buffer_access_funcs iio_cb_access = {
        .store_to = &iio_buffer_cb_store_to,
+       .release = &iio_buffer_cb_release,
 };
 
 struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
-                                            int (*cb)(u8 *data,
+                                            int (*cb)(const void *data,
                                                       void *private),
                                             void *private)
 {
@@ -104,9 +114,8 @@ EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb);
 
 void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff)
 {
-       kfree(cb_buff->buffer.scan_mask);
        iio_channel_release_all(cb_buff->channels);
-       kfree(cb_buff);
+       iio_buffer_put(&cb_buff->buffer);
 }
 EXPORT_SYMBOL_GPL(iio_channel_release_all_cb);
 
index 87419c41b991da24d8d284d33502c81f72c1c377..b6e77e0fc420133af7a324de6a0531bfb045f33d 100644 (file)
@@ -34,6 +34,12 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig,
        struct hid_sensor_common *st = iio_trigger_get_drvdata(trig);
        int state_val;
 
+       if (state) {
+               if (sensor_hub_device_open(st->hsdev))
+                       return -EIO;
+       } else
+               sensor_hub_device_close(st->hsdev);
+
        state_val = state ? 1 : 0;
        if (IS_ENABLED(CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS))
                ++state_val;
index 71a2c5f63b9ced2361c5fb94f255cc3c6430ba23..1665c8e4b62b245c4301a93143b1912ec140466d 100644 (file)
@@ -113,11 +113,8 @@ irqreturn_t st_sensors_trigger_handler(int irq, void *p)
        if (len < 0)
                goto st_sensors_get_buffer_element_error;
 
-       if (indio_dev->scan_timestamp)
-               *(s64 *)((u8 *)sdata->buffer_data +
-                               ALIGN(len, sizeof(s64))) = pf->timestamp;
-
-       iio_push_to_buffers(indio_dev, sdata->buffer_data);
+       iio_push_to_buffers_with_timestamp(indio_dev, sdata->buffer_data,
+               pf->timestamp);
 
 st_sensors_get_buffer_element_error:
        iio_trigger_notify_done(indio_dev->trig);
index 965ee22d3ac80ef1ae98d26da17d3a44528b43db..7ba1ef27021323ec82ccb8a2cb3242795bfb0116 100644 (file)
@@ -198,21 +198,17 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
 }
 EXPORT_SYMBOL(st_sensors_set_axis_enable);
 
-int st_sensors_init_sensor(struct iio_dev *indio_dev,
-                                       struct st_sensors_platform_data *pdata)
+static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
+                                      struct st_sensors_platform_data *pdata)
 {
-       int err;
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
-       mutex_init(&sdata->tb.buf_lock);
-
        switch (pdata->drdy_int_pin) {
        case 1:
                if (sdata->sensor->drdy_irq.mask_int1 == 0) {
                        dev_err(&indio_dev->dev,
                                        "DRDY on INT1 not available.\n");
-                       err = -EINVAL;
-                       goto init_error;
+                       return -EINVAL;
                }
                sdata->drdy_int_pin = 1;
                break;
@@ -220,39 +216,53 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
                if (sdata->sensor->drdy_irq.mask_int2 == 0) {
                        dev_err(&indio_dev->dev,
                                        "DRDY on INT2 not available.\n");
-                       err = -EINVAL;
-                       goto init_error;
+                       return -EINVAL;
                }
                sdata->drdy_int_pin = 2;
                break;
        default:
                dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
-               err = -EINVAL;
-               goto init_error;
+               return -EINVAL;
        }
 
+       return 0;
+}
+
+int st_sensors_init_sensor(struct iio_dev *indio_dev,
+                                       struct st_sensors_platform_data *pdata)
+{
+       struct st_sensor_data *sdata = iio_priv(indio_dev);
+       int err = 0;
+
+       mutex_init(&sdata->tb.buf_lock);
+
+       if (pdata)
+               err = st_sensors_set_drdy_int_pin(indio_dev, pdata);
+
        err = st_sensors_set_enable(indio_dev, false);
        if (err < 0)
-               goto init_error;
+               return err;
 
-       err = st_sensors_set_fullscale(indio_dev,
-                                               sdata->current_fullscale->num);
-       if (err < 0)
-               goto init_error;
+       if (sdata->current_fullscale) {
+               err = st_sensors_set_fullscale(indio_dev,
+                                              sdata->current_fullscale->num);
+               if (err < 0)
+                       return err;
+       } else
+               dev_info(&indio_dev->dev, "Full-scale not possible\n");
 
        err = st_sensors_set_odr(indio_dev, sdata->odr);
        if (err < 0)
-               goto init_error;
+               return err;
 
        /* set BDU */
        err = st_sensors_write_data_with_mask(indio_dev,
                        sdata->sensor->bdu.addr, sdata->sensor->bdu.mask, true);
        if (err < 0)
-               goto init_error;
+               return err;
 
        err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
 
-init_error:
        return err;
 }
 EXPORT_SYMBOL(st_sensors_init_sensor);
@@ -263,6 +273,9 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
        u8 drdy_mask;
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
+       if (!sdata->sensor->drdy_irq.addr)
+               return 0;
+
        /* Enable/Disable the interrupt generator 1. */
        if (sdata->sensor->drdy_irq.ig1.en_addr > 0) {
                err = st_sensors_write_data_with_mask(indio_dev,
@@ -318,10 +331,8 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
        unsigned int byte_for_channel = ch->scan_type.storagebits >> 3;
 
        outdata = kmalloc(byte_for_channel, GFP_KERNEL);
-       if (!outdata) {
-               err = -EINVAL;
-               goto st_sensors_read_axis_data_error;
-       }
+       if (!outdata)
+               return -ENOMEM;
 
        err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
                                ch->address, byte_for_channel,
@@ -336,7 +347,7 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
 
 st_sensors_free_memory:
        kfree(outdata);
-st_sensors_read_axis_data_error:
+
        return err;
 }
 
@@ -349,28 +360,25 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
        mutex_lock(&indio_dev->mlock);
        if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
                err = -EBUSY;
-               goto read_error;
+               goto out;
        } else {
                err = st_sensors_set_enable(indio_dev, true);
                if (err < 0)
-                       goto read_error;
+                       goto out;
 
                msleep((sdata->sensor->bootime * 1000) / sdata->odr);
                err = st_sensors_read_axis_data(indio_dev, ch, val);
                if (err < 0)
-                       goto read_error;
+                       goto out;
 
                *val = *val >> ch->scan_type.shift;
 
                err = st_sensors_set_enable(indio_dev, false);
        }
+out:
        mutex_unlock(&indio_dev->mlock);
 
        return err;
-
-read_error:
-       mutex_unlock(&indio_dev->mlock);
-       return err;
 }
 EXPORT_SYMBOL(st_sensors_read_info_raw);
 
index 3c6a78a75b78879558ff472c519ab567b01550e9..f378ca8033db699ff0753652cc0d92733119c56a 100644 (file)
@@ -57,7 +57,7 @@ config AD5446
          Say yes here to build support for Analog Devices AD5300, AD5301, AD5310,
          AD5311, AD5320, AD5321, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453,
          AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5602, AD5611, AD5612,
-         AD5620, AD5621, AD5622, AD5640, AD5660, AD5662 DACs.
+         AD5620, AD5621, AD5622, AD5640, AD5641, AD5660, AD5662 DACs.
 
          To compile this driver as a module, choose M here: the
          module will be called ad5446.
index a3a52be4852cb39fb3791b64f53cdbc285e87158..cb9c6366032cd2f8494236c52062e0b6caabdf92 100644 (file)
@@ -239,10 +239,9 @@ static int ad5064_read_raw(struct iio_dev *indio_dev,
                if (scale_uv < 0)
                        return scale_uv;
 
-               scale_uv = (scale_uv * 100) >> chan->scan_type.realbits;
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = scale_uv / 1000;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        default:
                break;
        }
@@ -285,8 +284,9 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
                .name = "powerdown",
                .read = ad5064_read_dac_powerdown,
                .write = ad5064_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &ad5064_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5064_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5064_powerdown_mode_enum),
        { },
 };
index d2da71ece740cbc1b0d62710d0afdbbba725ed91..b968af50db0a1cc2ffdb5565a0121b51d781cd61 100644 (file)
@@ -379,15 +379,14 @@ static int ad5360_read_raw(struct iio_dev *indio_dev,
                *val = ret >> chan->scan_type.shift;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               /* vout = 4 * vref * dac_code */
-               scale_uv = ad5360_get_channel_vref(st, chan->channel) * 4 * 100;
+               scale_uv = ad5360_get_channel_vref(st, chan->channel);
                if (scale_uv < 0)
                        return scale_uv;
 
-               scale_uv >>= (chan->scan_type.realbits);
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               /* vout = 4 * vref * dac_code */
+               *val = scale_uv * 4 / 1000;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_CALIBBIAS:
                ret = ad5360_read(indio_dev, AD5360_READBACK_OFFSET,
                        chan->address);
index 1c44ae3920e25b463bd907a3057a153fac3ba95f..a59ff0e7b8882139bcbf0e0fd1a55d75670486d1 100644 (file)
@@ -204,7 +204,6 @@ static int ad5380_read_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int *val, int *val2, long info)
 {
        struct ad5380_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
        int ret;
 
        switch (info) {
@@ -225,10 +224,9 @@ static int ad5380_read_raw(struct iio_dev *indio_dev,
                val -= (1 << chan->scan_type.realbits) / 2;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = ((2 * st->vref) >> chan->scan_type.realbits) * 100;
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = 2 * st->vref;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        default:
                break;
        }
@@ -247,8 +245,10 @@ static struct iio_chan_spec_ext_info ad5380_ext_info[] = {
                .name = "powerdown",
                .read = ad5380_read_dac_powerdown,
                .write = ad5380_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5380_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5380_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum),
        { },
 };
@@ -269,72 +269,72 @@ static const struct ad5380_chip_info ad5380_chip_info_tbl[] = {
        [ID_AD5380_3] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 40,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5380_5] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 40,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5381_3] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 16,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5381_5] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 16,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5382_3] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 32,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5382_5] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 32,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5383_3] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 32,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5383_5] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 32,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5390_3] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 16,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5390_5] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 16,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5391_3] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 16,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5391_5] = {
                .channel_template = AD5380_CHANNEL(12),
                .num_channels = 16,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
        [ID_AD5392_3] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 8,
-               .int_vref = 1250000,
+               .int_vref = 1250,
        },
        [ID_AD5392_5] = {
                .channel_template = AD5380_CHANNEL(14),
                .num_channels = 8,
-               .int_vref = 2500000,
+               .int_vref = 2500,
        },
 };
 
@@ -393,7 +393,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
                return ret;
        }
 
-       if (st->chip_info->int_vref == 2500000)
+       if (st->chip_info->int_vref == 2500)
                ctrl |= AD5380_CTRL_INT_VREF_2V5;
 
        st->vref_reg = devm_regulator_get(dev, "vref");
@@ -409,7 +409,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
                if (ret < 0)
                        goto error_disable_reg;
 
-               st->vref = ret;
+               st->vref = ret / 1000;
        } else {
                st->vref = st->chip_info->int_vref;
                ctrl |= AD5380_CTRL_INT_VREF_EN;
index 1f78b14abb7dc684e44e159816376181f591e070..c44afeb06f56ac890dd5a4ea38f9bde76dbeeec9 100644 (file)
@@ -80,6 +80,29 @@ struct ad5421_state {
        } data[2] ____cacheline_aligned;
 };
 
+static const struct iio_event_spec ad5421_current_event[] = {
+       {
+               .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),
+       },
+};
+
+static const struct iio_event_spec ad5421_temp_event[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
 static const struct iio_chan_spec ad5421_channels[] = {
        {
                .type = IIO_CURRENT,
@@ -92,13 +115,14 @@ static const struct iio_chan_spec ad5421_channels[] = {
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
                        BIT(IIO_CHAN_INFO_OFFSET),
                .scan_type = IIO_ST('u', 16, 16, 0),
-               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
-                       IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
+               .event_spec = ad5421_current_event,
+               .num_event_specs = ARRAY_SIZE(ad5421_current_event),
        },
        {
                .type = IIO_TEMP,
                .channel = -1,
-               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
+               .event_spec = ad5421_temp_event,
+               .num_event_specs = ARRAY_SIZE(ad5421_temp_event),
        },
 };
 
@@ -281,18 +305,11 @@ static inline unsigned int ad5421_get_offset(struct ad5421_state *st)
        return (min * (1 << 16)) / (max - min);
 }
 
-static inline unsigned int ad5421_get_scale(struct ad5421_state *st)
-{
-       unsigned int min, max;
-
-       ad5421_get_current_min_max(st, &min, &max);
-       return ((max - min) * 1000) / (1 << 16);
-}
-
 static int ad5421_read_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int *val, int *val2, long m)
 {
        struct ad5421_state *st = iio_priv(indio_dev);
+       unsigned int min, max;
        int ret;
 
        if (chan->type != IIO_CURRENT)
@@ -306,9 +323,10 @@ static int ad5421_read_raw(struct iio_dev *indio_dev,
                *val = ret;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               *val = 0;
-               *val2 = ad5421_get_scale(st);
-               return IIO_VAL_INT_PLUS_MICRO;
+               ad5421_get_current_min_max(st, &min, &max);
+               *val = max - min;
+               *val2 = (1 << 16) * 1000;
+               return IIO_VAL_FRACTIONAL;
        case IIO_CHAN_INFO_OFFSET:
                *val = ad5421_get_offset(st);
                return IIO_VAL_INT;
@@ -359,15 +377,15 @@ static int ad5421_write_raw(struct iio_dev *indio_dev,
 }
 
 static int ad5421_write_event_config(struct iio_dev *indio_dev,
-       u64 event_code, int state)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, int state)
 {
        struct ad5421_state *st = iio_priv(indio_dev);
        unsigned int mask;
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_CURRENT:
-               if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING)
+               if (dir == IIO_EV_DIR_RISING)
                        mask = AD5421_FAULT_OVER_CURRENT;
                else
                        mask = AD5421_FAULT_UNDER_CURRENT;
@@ -390,15 +408,15 @@ static int ad5421_write_event_config(struct iio_dev *indio_dev,
 }
 
 static int ad5421_read_event_config(struct iio_dev *indio_dev,
-       u64 event_code)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir)
 {
        struct ad5421_state *st = iio_priv(indio_dev);
        unsigned int mask;
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_CURRENT:
-               if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING)
+               if (dir == IIO_EV_DIR_RISING)
                        mask = AD5421_FAULT_OVER_CURRENT;
                else
                        mask = AD5421_FAULT_UNDER_CURRENT;
@@ -413,12 +431,14 @@ static int ad5421_read_event_config(struct iio_dev *indio_dev,
        return (bool)(st->fault_mask & mask);
 }
 
-static int ad5421_read_event_value(struct iio_dev *indio_dev, u64 event_code,
-       int *val)
+static int ad5421_read_event_value(struct iio_dev *indio_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)
 {
        int ret;
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_CURRENT:
                ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA);
                if (ret < 0)
@@ -432,15 +452,15 @@ static int ad5421_read_event_value(struct iio_dev *indio_dev, u64 event_code,
                return -EINVAL;
        }
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
 static const struct iio_info ad5421_info = {
        .read_raw =             ad5421_read_raw,
        .write_raw =            ad5421_write_raw,
-       .read_event_config =    ad5421_read_event_config,
-       .write_event_config =   ad5421_write_event_config,
-       .read_event_value =     ad5421_read_event_value,
+       .read_event_config_new = ad5421_read_event_config,
+       .write_event_config_new = ad5421_write_event_config,
+       .read_event_value_new = ad5421_read_event_value,
        .driver_module =        THIS_MODULE,
 };
 
index 96e9ed4c2d0167f1274ecbc6307a28d4594dbf10..1263b0e5ad84fda9dfdd841bbc23498d19918937 100644 (file)
@@ -132,8 +132,9 @@ static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = {
                .name = "powerdown",
                .read = ad5446_read_dac_powerdown,
                .write = ad5446_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &ad5446_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5446_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5446_powerdown_mode_enum),
        { },
 };
@@ -162,18 +163,15 @@ static int ad5446_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad5446_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_RAW:
                *val = st->cached_val;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
-
+               *val = st->vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -329,6 +327,7 @@ enum ad5446_supported_spi_device_ids {
        ID_AD5601,
        ID_AD5611,
        ID_AD5621,
+       ID_AD5641,
        ID_AD5620_2500,
        ID_AD5620_1250,
        ID_AD5640_2500,
@@ -391,6 +390,10 @@ static const struct ad5446_chip_info ad5446_spi_chip_info[] = {
                .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
                .write = ad5446_write,
        },
+       [ID_AD5641] = {
+               .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0),
+               .write = ad5446_write,
+       },
        [ID_AD5620_2500] = {
                .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2),
                .int_vref_mv = 2500,
@@ -445,6 +448,7 @@ static const struct spi_device_id ad5446_spi_ids[] = {
        {"ad5601", ID_AD5601},
        {"ad5611", ID_AD5611},
        {"ad5621", ID_AD5621},
+       {"ad5641", ID_AD5641},
        {"ad5620-2500", ID_AD5620_2500}, /* AD5620/40/60: */
        {"ad5620-1250", ID_AD5620_1250}, /* part numbers may look differently */
        {"ad5640-2500", ID_AD5640_2500},
index fff7d0762c0cb10fd4afbc40d9ac6799e10dad31..82e208f6cde2021f8707e1f45d9a3e3c8a528664 100644 (file)
@@ -101,7 +101,6 @@ static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr,
 {
        struct ad5449 *st = iio_priv(indio_dev);
        int ret;
-       struct spi_message msg;
        struct spi_transfer t[] = {
                {
                        .tx_buf = &st->data[0],
@@ -114,15 +113,11 @@ static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr,
                },
        };
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&t[0], &msg);
-       spi_message_add_tail(&t[1], &msg);
-
        mutex_lock(&indio_dev->mlock);
        st->data[0] = cpu_to_be16(addr << 12);
        st->data[1] = cpu_to_be16(AD5449_CMD_NOOP);
 
-       ret = spi_sync(st->spi, &msg);
+       ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
        if (ret < 0)
                goto out_unlock;
 
index caffb16bc05c0ce34b9fa6c65ebfd433ec57bf8f..c0957a918e17128b31bf7c1a4fbf743253b3cca3 100644 (file)
@@ -100,7 +100,6 @@ static int ad5504_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad5504_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
        int ret;
 
        switch (m) {
@@ -113,11 +112,9 @@ static int ad5504_read_raw(struct iio_dev *indio_dev,
 
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
-
+               *val = st->vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -248,8 +245,10 @@ static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
                .name = "powerdown",
                .read = ad5504_read_dac_powerdown,
                .write = ad5504_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5504_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum),
        { },
 };
index 714af757cd561cc291d88d04c9d00dc2cab8ed1a..774dd968145bd0515bad4799b805b4741f7fdb9e 100644 (file)
@@ -50,15 +50,12 @@ static int ad5624r_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad5624r_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
-
+               *val = st->vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -163,8 +160,10 @@ static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
                .name = "powerdown",
                .read = ad5624r_read_dac_powerdown,
                .write = ad5624r_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5624r_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum),
        { },
 };
index 57825ead7db2eec071cf7d593bfbcb642bfa9784..30e506e37dd26adb6ad0510f8be0f1ca298b786d 100644 (file)
@@ -201,7 +201,6 @@ static int ad5686_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad5686_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
        int ret;
 
        switch (m) {
@@ -213,14 +212,10 @@ static int ad5686_read_raw(struct iio_dev *indio_dev,
                        return ret;
                *val = ret;
                return IIO_VAL_INT;
-               break;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->vref_mv * 100000)
-                       >> (chan->scan_type.realbits);
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
-
+               *val = st->vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -265,8 +260,9 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
                .name = "powerdown",
                .read = ad5686_read_dac_powerdown,
                .write = ad5686_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &ad5686_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5686_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
        { },
 };
index 36a4361aece12b771169a541e993eead076c602a..bd31dbc340c106cb7ebfc44b5a2e14188fd9efc2 100644 (file)
@@ -253,15 +253,6 @@ static inline int ad5755_get_offset(struct ad5755_state *st,
        return (min * (1 << chan->scan_type.realbits)) / (max - min);
 }
 
-static inline int ad5755_get_scale(struct ad5755_state *st,
-       struct iio_chan_spec const *chan)
-{
-       int min, max;
-
-       ad5755_get_min_max(st, chan, &min, &max);
-       return ((max - min) * 1000000000ULL) >> chan->scan_type.realbits;
-}
-
 static int ad5755_chan_reg_info(struct ad5755_state *st,
        struct iio_chan_spec const *chan, long info, bool write,
        unsigned int *reg, unsigned int *shift, unsigned int *offset)
@@ -303,13 +294,15 @@ static int ad5755_read_raw(struct iio_dev *indio_dev,
 {
        struct ad5755_state *st = iio_priv(indio_dev);
        unsigned int reg, shift, offset;
+       int min, max;
        int ret;
 
        switch (info) {
        case IIO_CHAN_INFO_SCALE:
-               *val = 0;
-               *val2 = ad5755_get_scale(st, chan);
-               return IIO_VAL_INT_PLUS_NANO;
+               ad5755_get_min_max(st, chan, &min, &max);
+               *val = max - min;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_OFFSET:
                *val = ad5755_get_offset(st, chan);
                return IIO_VAL_INT;
@@ -386,6 +379,7 @@ static const struct iio_chan_spec_ext_info ad5755_ext_info[] = {
                .name = "powerdown",
                .read = ad5755_read_powerdown,
                .write = ad5755_write_powerdown,
+               .shared = IIO_SEPARATE,
        },
        { },
 };
index df7e028d9db5ef618549e5c08ca82158be58abef..a8ff5b2ed13ef396440b93cddc74d5f0a2397303 100644 (file)
@@ -217,7 +217,6 @@ static int ad5764_read_raw(struct iio_dev *indio_dev,
        struct iio_chan_spec const *chan, int *val, int *val2, long info)
 {
        struct ad5764_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
        unsigned int reg;
        int vref;
        int ret;
@@ -245,15 +244,14 @@ static int ad5764_read_raw(struct iio_dev *indio_dev,
                *val = sign_extend32(*val, 5);
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               /* vout = 4 * vref + ((dac_code / 65535) - 0.5) */
+               /* vout = 4 * vref + ((dac_code / 65536) - 0.5) */
                vref = ad5764_get_channel_vref(st, chan->channel);
                if (vref < 0)
                        return vref;
 
-               scale_uv = (vref * 4 * 100) >> chan->scan_type.realbits;
-               *val = scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = vref * 4 / 1000;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_OFFSET:
                *val = -(1 << chan->scan_type.realbits) / 2;
                return IIO_VAL_INT;
index ce7458963309aa4fd08a82c8d9274d02090d2174..d64acbd89482b82308601d88cb742446b865856a 100644 (file)
@@ -270,9 +270,9 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
                *val >>= chan->scan_type.shift;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               *val = 0;
-               *val2 = (((u64)st->vref_mv) * 1000000ULL) >> chan->scan_type.realbits;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->vref_mv;
+               *val2 = (1 << chan->scan_type.realbits) - 1;
+               return IIO_VAL_FRACTIONAL;
        case IIO_CHAN_INFO_OFFSET:
                val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
                do_div(val64, st->vref_mv);
@@ -287,11 +287,12 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
 static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
        {
                .name = "powerdown",
-               .shared = true,
+               .shared = IIO_SHARED_BY_TYPE,
                .read = ad5791_read_dac_powerdown,
                .write = ad5791_write_dac_powerdown,
        },
-       IIO_ENUM("powerdown_mode", true, &ad5791_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
+                &ad5791_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
        { },
 };
index ed2d276477bd9970aeede225b93b7cc56c8ab40e..d0505fd22ef46c467d99f6b7e9dca18b9a4a688d 100644 (file)
@@ -169,6 +169,7 @@ static const struct iio_chan_spec_ext_info ad7303_ext_info[] = {
                .name = "powerdown",
                .read = ad7303_read_dac_powerdown,
                .write = ad7303_write_dac_powerdown,
+               .shared = IIO_SEPARATE,
        },
        { },
 };
index 83adcbf1a205e73f173763258c08b5cac2f9ad06..d26be14fff6405eaf5105f25a6b9395b367ecbd7 100644 (file)
@@ -82,15 +82,13 @@ static int max517_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct max517_data *data = iio_priv(indio_dev);
-       unsigned int scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_SCALE:
                /* Corresponds to Vref / 2^(bits) */
-               scale_uv = (data->vref_mv[chan->channel] * 1000) >> 8;
-               *val =  scale_uv / 1000000;
-               *val2 = scale_uv % 1000000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = data->vref_mv[chan->channel];
+               *val2 = 8;
+               return IIO_VAL_FRACTIONAL_LOG2;
        default:
                break;
        }
index 1397b6e0e414c25835aebd829dc2bede15dedee3..d982752dd9c415263c3e79fe7193ccb86abaccda 100644 (file)
@@ -195,8 +195,9 @@ static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
                .name = "powerdown",
                .read = mcp4725_read_powerdown,
                .write = mcp4725_write_powerdown,
+               .shared = IIO_SEPARATE,
        },
-       IIO_ENUM("powerdown_mode", false, &mcp4725_powerdown_mode_enum),
+       IIO_ENUM("powerdown_mode", IIO_SEPARATE, &mcp4725_powerdown_mode_enum),
        IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum),
        { },
 };
@@ -238,17 +239,15 @@ static int mcp4725_read_raw(struct iio_dev *indio_dev,
                           int *val, int *val2, long mask)
 {
        struct mcp4725_data *data = iio_priv(indio_dev);
-       unsigned long scale_uv;
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
                *val = data->dac_value;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (data->vref_mv * 1000) >> 12;
-               *val =  scale_uv / 1000000;
-               *val2 = scale_uv % 1000000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = data->vref_mv;
+               *val2 = 12;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
index 52605c0ea3a69fce7c1d312d4fa1610de43174fd..63a25d9e120486db1dd1c023b0b0456f32da68a1 100644 (file)
@@ -351,6 +351,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
        .read = adf4350_read, \
        .write = adf4350_write, \
        .private = _ident, \
+       .shared = IIO_SEPARATE, \
 }
 
 static const struct iio_chan_spec_ext_info adf4350_ext_info[] = {
index e9ec022ae2250c62f6400ae1a9ee5dbdf06a9c30..add509837269ba8868f717950256fa9670174a17 100644 (file)
@@ -51,7 +51,6 @@ static int adis16080_read_sample(struct iio_dev *indio_dev,
                u16 addr, int *val)
 {
        struct adis16080_state *st = iio_priv(indio_dev);
-       struct spi_message m;
        int ret;
        struct spi_transfer     t[] = {
                {
@@ -66,11 +65,7 @@ static int adis16080_read_sample(struct iio_dev *indio_dev,
 
        st->buf = cpu_to_be16(addr | ADIS16080_DIN_WRITE);
 
-       spi_message_init(&m);
-       spi_message_add_tail(&t[0], &m);
-       spi_message_add_tail(&t[1], &m);
-
-       ret = spi_sync(st->us, &m);
+       ret = spi_sync_transfer(st->us, t, ARRAY_SIZE(t));
        if (ret == 0)
                *val = sign_extend32(be16_to_cpu(st->buf), 11);
 
index ac66fc184042e4aa7e23545555321521a032df31..445c2aecfadde205921049a1e0b42d64342318d5 100644 (file)
@@ -47,7 +47,6 @@ static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
 {
        int ret;
        struct adis16130_state *st = iio_priv(indio_dev);
-       struct spi_message msg;
        struct spi_transfer xfer = {
                .tx_buf = st->buf,
                .rx_buf = st->buf,
@@ -59,10 +58,7 @@ static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
        st->buf[0] = ADIS16130_CON_RD | reg_addr;
        st->buf[1] = st->buf[2] = st->buf[3] = 0;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->us, &msg);
-
+       ret = spi_sync_transfer(st->us, &xfer, 1);
        if (ret == 0)
                *val = (st->buf[1] << 16) | (st->buf[2] << 8) | st->buf[3];
        mutex_unlock(&st->buf_lock);
@@ -103,7 +99,6 @@ static int adis16130_read_raw(struct iio_dev *indio_dev,
                default:
                        return -EINVAL;
                }
-               break;
        case IIO_CHAN_INFO_OFFSET:
                switch (chan->type) {
                case IIO_ANGL_VEL:
@@ -115,7 +110,6 @@ static int adis16130_read_raw(struct iio_dev *indio_dev,
                default:
                        return -EINVAL;
                }
-               break;
        }
 
        return -EINVAL;
index 06541162fc0213676467d3028f9ae1dde70cb848..22b6fb80fa1a7a99d3003d15e44fd63ac07f10b2 100644 (file)
@@ -239,7 +239,6 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
                default:
                        return -EINVAL;
                }
-               break;
        case IIO_CHAN_INFO_OFFSET:
                *val = 250000 / 1453; /* 25 C = 0x00 */
                return IIO_VAL_INT;
index 6dab2995f0f26ebc5111b75281722ea029ee3c8c..1e546ba7ba45e1c92acf9ae926b9c29c386785ef 100644 (file)
@@ -90,7 +90,6 @@ static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,
                                    u8 reg_address,
                                    u16 *val)
 {
-       struct spi_message msg;
        struct adxrs450_state *st = iio_priv(indio_dev);
        u32 tx;
        int ret;
@@ -114,10 +113,7 @@ static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,
                tx |= ADXRS450_P;
 
        st->tx = cpu_to_be32(tx);
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-       ret = spi_sync(st->us, &msg);
+       ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
        if (ret) {
                dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n",
                                reg_address);
@@ -169,7 +165,6 @@ static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev,
  **/
 static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val)
 {
-       struct spi_message msg;
        struct adxrs450_state *st = iio_priv(indio_dev);
        int ret;
        struct spi_transfer xfers[] = {
@@ -188,10 +183,7 @@ static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val)
        mutex_lock(&st->buf_lock);
        st->tx = cpu_to_be32(ADXRS450_SENSOR_DATA);
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-       ret = spi_sync(st->us, &msg);
+       ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
        if (ret) {
                dev_err(&st->us->dev, "Problem while reading sensor data\n");
                goto error_ret;
@@ -354,7 +346,6 @@ static int adxrs450_read_raw(struct iio_dev *indio_dev,
                default:
                        return -EINVAL;
                }
-               break;
        case IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW:
                ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_QUAD1, &t);
                if (ret)
index c688d974d3e3ec3d858a4f07e6dabf592866a395..ea01c6bcfb56825979efc7bfc588eeb9e429e059 100644 (file)
@@ -182,10 +182,11 @@ static const struct iio_info gyro_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+       int len)
 {
        dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+       iio_push_to_buffers(indio_dev, data);
 }
 
 /* Callback handler to send event after all samples are received and captured */
@@ -200,7 +201,7 @@ static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
                                gyro_state->common_attributes.data_ready);
        if (gyro_state->common_attributes.data_ready)
                hid_sensor_push_data(indio_dev,
-                               (u8 *)gyro_state->gyro_val,
+                               gyro_state->gyro_val,
                                sizeof(gyro_state->gyro_val));
 
        return 0;
index 6c43af9bb0a4474097f2def7ec15d973a7238b47..e3b3c5084070d808ca88939e3f13257472ba3e55 100644 (file)
@@ -55,11 +55,8 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)
        if (ret < 0)
                goto error_ret;
 
-       if (indio_dev->scan_timestamp)
-               memcpy(buf + indio_dev->scan_bytes - sizeof(s64),
-                               &pf->timestamp, sizeof(pf->timestamp));
+       iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp);
 
-       iio_push_to_buffers(indio_dev, (u8 *)buf);
        iio_trigger_notify_done(indio_dev->trig);
 
 error_ret:
index 69017c7ec302a785ffd86afca90ff3b2ae1e9d3e..d67b17b6a7aab1abd0077e297c5e0f9769eee893 100644 (file)
@@ -32,16 +32,7 @@ int st_gyro_trig_set_state(struct iio_trigger *trig, bool state)
 
 static int st_gyro_buffer_preenable(struct iio_dev *indio_dev)
 {
-       int err;
-
-       err = st_sensors_set_enable(indio_dev, true);
-       if (err < 0)
-               goto st_gyro_set_enable_error;
-
-       err = iio_sw_buffer_preenable(indio_dev);
-
-st_gyro_set_enable_error:
-       return err;
+       return st_sensors_set_enable(indio_dev, true);
 }
 
 static int st_gyro_buffer_postenable(struct iio_dev *indio_dev)
index e13c2b0bf3d1ae27de590555d349b6b31632f112..d53d91adfb557b0e575a17030221c6e01b2b7d38 100644 (file)
@@ -305,8 +305,9 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = {
 int st_gyro_common_probe(struct iio_dev *indio_dev,
                                        struct st_sensors_platform_data *pdata)
 {
-       int err;
        struct st_sensor_data *gdata = iio_priv(indio_dev);
+       int irq = gdata->get_irq_data_ready(indio_dev);
+       int err;
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &gyro_info;
@@ -314,7 +315,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
        err = st_sensors_check_device_support(indio_dev,
                                ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
        if (err < 0)
-               goto st_gyro_common_probe_error;
+               return err;
 
        gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
        gdata->multiread_bit = gdata->sensor->multi_read_bit;
@@ -327,13 +328,13 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
 
        err = st_sensors_init_sensor(indio_dev, pdata);
        if (err < 0)
-               goto st_gyro_common_probe_error;
+               return err;
 
-       if (gdata->get_irq_data_ready(indio_dev) > 0) {
-               err = st_gyro_allocate_ring(indio_dev);
-               if (err < 0)
-                       goto st_gyro_common_probe_error;
+       err = st_gyro_allocate_ring(indio_dev);
+       if (err < 0)
+               return err;
 
+       if (irq > 0) {
                err = st_sensors_allocate_trigger(indio_dev,
                                                  ST_GYRO_TRIGGER_OPS);
                if (err < 0)
@@ -344,15 +345,14 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
        if (err)
                goto st_gyro_device_register_error;
 
-       return err;
+       return 0;
 
 st_gyro_device_register_error:
-       if (gdata->get_irq_data_ready(indio_dev) > 0)
+       if (irq > 0)
                st_sensors_deallocate_trigger(indio_dev);
 st_gyro_probe_trigger_error:
-       if (gdata->get_irq_data_ready(indio_dev) > 0)
-               st_gyro_deallocate_ring(indio_dev);
-st_gyro_common_probe_error:
+       st_gyro_deallocate_ring(indio_dev);
+
        return err;
 }
 EXPORT_SYMBOL(st_gyro_common_probe);
@@ -362,10 +362,10 @@ void st_gyro_common_remove(struct iio_dev *indio_dev)
        struct st_sensor_data *gdata = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (gdata->get_irq_data_ready(indio_dev) > 0) {
+       if (gdata->get_irq_data_ready(indio_dev) > 0)
                st_sensors_deallocate_trigger(indio_dev);
-               st_gyro_deallocate_ring(indio_dev);
-       }
+
+       st_gyro_deallocate_ring(indio_dev);
 }
 EXPORT_SYMBOL(st_gyro_common_remove);
 
index 9b32253b824be454bf2f6c46bf02acb022b3be46..f6db6af36ba6de20ceb2cf9dc159dff9f53a1987 100644 (file)
@@ -30,9 +30,12 @@ int __iio_add_chan_devattr(const char *postfix,
                                                const char *buf,
                                                size_t len),
                           u64 mask,
-                          bool generic,
+                          enum iio_shared_by shared_by,
                           struct device *dev,
                           struct list_head *attr_list);
+void iio_free_chan_devattr_list(struct list_head *attr_list);
+
+ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2);
 
 /* Event interface flags */
 #define IIO_BUSY_BIT_POS 1
@@ -50,6 +53,7 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
 #define iio_buffer_read_first_n_outer_addr (&iio_buffer_read_first_n_outer)
 
 void iio_disable_all_buffers(struct iio_dev *indio_dev);
+void iio_buffer_wakeup_poll(struct iio_dev *indio_dev);
 
 #else
 
@@ -57,11 +61,13 @@ void iio_disable_all_buffers(struct iio_dev *indio_dev);
 #define iio_buffer_read_first_n_outer_addr NULL
 
 static inline void iio_disable_all_buffers(struct iio_dev *indio_dev) {}
+static inline void iio_buffer_wakeup_poll(struct iio_dev *indio_dev) {}
 
 #endif
 
 int iio_device_register_eventset(struct iio_dev *indio_dev);
 void iio_device_unregister_eventset(struct iio_dev *indio_dev);
+void iio_device_wakeup_eventset(struct iio_dev *indio_dev);
 int iio_event_getfd(struct iio_dev *indio_dev);
 
 #endif
index 054c01d6e73cf147845ea3da748fcb05068a3505..f2cf829e5df104ea35b64a0493c4975493826bcb 100644 (file)
@@ -82,13 +82,8 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p)
                spi_setup(st->adis.spi);
        }
 
-       /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp) {
-               void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
-               *(s64 *)b = pf->timestamp;
-       }
-
-       iio_push_to_buffers(indio_dev, adis->buffer);
+       iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
+               pf->timestamp);
 
        iio_trigger_notify_done(indio_dev->trig);
 
index 99d8e0b0dd34243168a750794df130ee77d8fe37..cb32b593f1c55c023046d97cfc41263ea3818d89 100644 (file)
@@ -102,13 +102,8 @@ static irqreturn_t adis_trigger_handler(int irq, void *p)
                mutex_unlock(&adis->txrx_lock);
        }
 
-       /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp) {
-               void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
-               *(s64 *)b = pf->timestamp;
-       }
-
-       iio_push_to_buffers(indio_dev, adis->buffer);
+       iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
+               pf->timestamp);
 
        iio_trigger_notify_done(indio_dev->trig);
 
index 7da0832f187b8d320cd8618eb3379b2015bee927..429517117eff43d92b86238a284635c8b3b4b8f9 100644 (file)
@@ -124,7 +124,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
        u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
        u16 fifo_count;
        s64 timestamp;
-       u64 *tmp;
 
        mutex_lock(&indio_dev->mlock);
        if (!(st->chip_config.accl_fifo_enable |
@@ -170,9 +169,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
                if (0 == result)
                        timestamp = 0;
 
-               tmp = (u64 *)data;
-               tmp[DIV_ROUND_UP(bytes_per_datum, 8)] = timestamp;
-               result = iio_push_to_buffers(indio_dev, data);
+               result = iio_push_to_buffers_with_timestamp(indio_dev, data,
+                       timestamp);
                if (result)
                        goto flush_fifo;
                fifo_count -= bytes_per_datum;
index 2db7dcd826b9db6500e354498b385cbb3ebd9f7d..7f9152c3c4d3dafa61f2cac1126b1cbd50306a6e 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/cdev.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
+#include <linux/sched.h>
 
 #include <linux/iio/iio.h>
 #include "iio_core.h"
@@ -31,16 +32,9 @@ static const char * const iio_endian_prefix[] = {
        [IIO_LE] = "le",
 };
 
-static bool iio_buffer_is_active(struct iio_dev *indio_dev,
-                                struct iio_buffer *buf)
+static bool iio_buffer_is_active(struct iio_buffer *buf)
 {
-       struct list_head *p;
-
-       list_for_each(p, &indio_dev->buffer_list)
-               if (p == &buf->buffer_list)
-                       return true;
-
-       return false;
+       return !list_empty(&buf->buffer_list);
 }
 
 /**
@@ -55,6 +49,9 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,
        struct iio_dev *indio_dev = filp->private_data;
        struct iio_buffer *rb = indio_dev->buffer;
 
+       if (!indio_dev->info)
+               return -ENODEV;
+
        if (!rb || !rb->access->read_first_n)
                return -EINVAL;
        return rb->access->read_first_n(rb, n, buf);
@@ -69,6 +66,9 @@ unsigned int iio_buffer_poll(struct file *filp,
        struct iio_dev *indio_dev = filp->private_data;
        struct iio_buffer *rb = indio_dev->buffer;
 
+       if (!indio_dev->info)
+               return -ENODEV;
+
        poll_wait(filp, &rb->pollq, wait);
        if (rb->stufftoread)
                return POLLIN | POLLRDNORM;
@@ -76,10 +76,27 @@ unsigned int iio_buffer_poll(struct file *filp,
        return 0;
 }
 
+/**
+ * iio_buffer_wakeup_poll - Wakes up the buffer waitqueue
+ * @indio_dev: The IIO device
+ *
+ * Wakes up the event waitqueue used for poll(). Should usually
+ * be called when the device is unregistered.
+ */
+void iio_buffer_wakeup_poll(struct iio_dev *indio_dev)
+{
+       if (!indio_dev->buffer)
+               return;
+
+       wake_up(&indio_dev->buffer->pollq);
+}
+
 void iio_buffer_init(struct iio_buffer *buffer)
 {
        INIT_LIST_HEAD(&buffer->demux_list);
+       INIT_LIST_HEAD(&buffer->buffer_list);
        init_waitqueue_head(&buffer->pollq);
+       kref_init(&buffer->ref);
 }
 EXPORT_SYMBOL(iio_buffer_init);
 
@@ -146,7 +163,7 @@ static ssize_t iio_scan_el_store(struct device *dev,
        if (ret < 0)
                return ret;
        mutex_lock(&indio_dev->mlock);
-       if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
+       if (iio_buffer_is_active(indio_dev->buffer)) {
                ret = -EBUSY;
                goto error_ret;
        }
@@ -192,7 +209,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
                return ret;
 
        mutex_lock(&indio_dev->mlock);
-       if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
+       if (iio_buffer_is_active(indio_dev->buffer)) {
                ret = -EBUSY;
                goto error_ret;
        }
@@ -214,7 +231,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
                                     &iio_show_scan_index,
                                     NULL,
                                     0,
-                                    0,
+                                    IIO_SEPARATE,
                                     &indio_dev->dev,
                                     &buffer->scan_el_dev_attr_list);
        if (ret)
@@ -249,29 +266,14 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
                                             0,
                                             &indio_dev->dev,
                                             &buffer->scan_el_dev_attr_list);
+       if (ret)
+               goto error_ret;
        attrcount++;
        ret = attrcount;
 error_ret:
        return ret;
 }
 
-static void iio_buffer_remove_and_free_scan_dev_attr(struct iio_dev *indio_dev,
-                                                    struct iio_dev_attr *p)
-{
-       kfree(p->dev_attr.attr.name);
-       kfree(p);
-}
-
-static void __iio_buffer_attr_cleanup(struct iio_dev *indio_dev)
-{
-       struct iio_dev_attr *p, *n;
-       struct iio_buffer *buffer = indio_dev->buffer;
-
-       list_for_each_entry_safe(p, n,
-                                &buffer->scan_el_dev_attr_list, l)
-               iio_buffer_remove_and_free_scan_dev_attr(indio_dev, p);
-}
-
 static const char * const iio_scan_elements_group_name = "scan_elements";
 
 int iio_buffer_register(struct iio_dev *indio_dev,
@@ -348,7 +350,7 @@ int iio_buffer_register(struct iio_dev *indio_dev,
 error_free_scan_mask:
        kfree(buffer->scan_mask);
 error_cleanup_dynamic:
-       __iio_buffer_attr_cleanup(indio_dev);
+       iio_free_chan_devattr_list(&buffer->scan_el_dev_attr_list);
 
        return ret;
 }
@@ -358,7 +360,7 @@ void iio_buffer_unregister(struct iio_dev *indio_dev)
 {
        kfree(indio_dev->buffer->scan_mask);
        kfree(indio_dev->buffer->scan_el_group.attrs);
-       __iio_buffer_attr_cleanup(indio_dev);
+       iio_free_chan_devattr_list(&indio_dev->buffer->scan_el_dev_attr_list);
 }
 EXPORT_SYMBOL(iio_buffer_unregister);
 
@@ -396,7 +398,7 @@ ssize_t iio_buffer_write_length(struct device *dev,
                        return len;
 
        mutex_lock(&indio_dev->mlock);
-       if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
+       if (iio_buffer_is_active(indio_dev->buffer)) {
                ret = -EBUSY;
        } else {
                if (buffer->access->set_length)
@@ -414,13 +416,11 @@ ssize_t iio_buffer_show_enable(struct device *dev,
                               char *buf)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       return sprintf(buf, "%d\n",
-                      iio_buffer_is_active(indio_dev,
-                                           indio_dev->buffer));
+       return sprintf(buf, "%d\n", iio_buffer_is_active(indio_dev->buffer));
 }
 EXPORT_SYMBOL(iio_buffer_show_enable);
 
-/* note NULL used as error indicator as it doesn't make sense. */
+/* Note NULL used as error indicator as it doesn't make sense. */
 static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
                                          unsigned int masklength,
                                          const unsigned long *mask)
@@ -435,8 +435,8 @@ static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
        return NULL;
 }
 
-static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask,
-                                 bool timestamp)
+static int iio_compute_scan_bytes(struct iio_dev *indio_dev,
+                               const unsigned long *mask, bool timestamp)
 {
        const struct iio_chan_spec *ch;
        unsigned bytes = 0;
@@ -460,6 +460,19 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask,
        return bytes;
 }
 
+static void iio_buffer_activate(struct iio_dev *indio_dev,
+       struct iio_buffer *buffer)
+{
+       iio_buffer_get(buffer);
+       list_add(&buffer->buffer_list, &indio_dev->buffer_list);
+}
+
+static void iio_buffer_deactivate(struct iio_buffer *buffer)
+{
+       list_del_init(&buffer->buffer_list);
+       iio_buffer_put(buffer);
+}
+
 void iio_disable_all_buffers(struct iio_dev *indio_dev)
 {
        struct iio_buffer *buffer, *_buffer;
@@ -472,7 +485,7 @@ void iio_disable_all_buffers(struct iio_dev *indio_dev)
 
        list_for_each_entry_safe(buffer, _buffer,
                        &indio_dev->buffer_list, buffer_list)
-               list_del_init(&buffer->buffer_list);
+               iio_buffer_deactivate(buffer);
 
        indio_dev->currentmode = INDIO_DIRECT_MODE;
        if (indio_dev->setup_ops->postdisable)
@@ -482,7 +495,21 @@ void iio_disable_all_buffers(struct iio_dev *indio_dev)
                kfree(indio_dev->active_scan_mask);
 }
 
-int iio_update_buffers(struct iio_dev *indio_dev,
+static void iio_buffer_update_bytes_per_datum(struct iio_dev *indio_dev,
+       struct iio_buffer *buffer)
+{
+       unsigned int bytes;
+
+       if (!buffer->access->set_bytes_per_datum)
+               return;
+
+       bytes = iio_compute_scan_bytes(indio_dev, buffer->scan_mask,
+               buffer->scan_timestamp);
+
+       buffer->access->set_bytes_per_datum(buffer, bytes);
+}
+
+static int __iio_update_buffers(struct iio_dev *indio_dev,
                       struct iio_buffer *insert_buffer,
                       struct iio_buffer *remove_buffer)
 {
@@ -512,9 +539,9 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                indio_dev->active_scan_mask = NULL;
 
        if (remove_buffer)
-               list_del(&remove_buffer->buffer_list);
+               iio_buffer_deactivate(remove_buffer);
        if (insert_buffer)
-               list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list);
+               iio_buffer_activate(indio_dev, insert_buffer);
 
        /* If no buffers in list, we are done */
        if (list_empty(&indio_dev->buffer_list)) {
@@ -524,7 +551,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                return 0;
        }
 
-       /* What scan mask do we actually have ?*/
+       /* What scan mask do we actually have*/
        compound_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
                                sizeof(long), GFP_KERNEL);
        if (compound_mask == NULL) {
@@ -549,7 +576,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                         * Roll back.
                         * Note can only occur when adding a buffer.
                         */
-                       list_del(&insert_buffer->buffer_list);
+                       iio_buffer_deactivate(insert_buffer);
                        if (old_mask) {
                                indio_dev->active_scan_mask = old_mask;
                                success = -EINVAL;
@@ -579,7 +606,8 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                iio_compute_scan_bytes(indio_dev,
                                       indio_dev->active_scan_mask,
                                       indio_dev->scan_timestamp);
-       list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
+       list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) {
+               iio_buffer_update_bytes_per_datum(indio_dev, buffer);
                if (buffer->access->request_update) {
                        ret = buffer->access->request_update(buffer);
                        if (ret) {
@@ -588,6 +616,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                                goto error_run_postdisable;
                        }
                }
+       }
        if (indio_dev->info->update_scan_mode) {
                ret = indio_dev->info
                        ->update_scan_mode(indio_dev,
@@ -597,7 +626,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                        goto error_run_postdisable;
                }
        }
-       /* Definitely possible for devices to support both of these.*/
+       /* Definitely possible for devices to support both of these. */
        if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
                if (!indio_dev->trig) {
                        printk(KERN_INFO "Buffer not started: no trigger\n");
@@ -608,7 +637,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
                indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
        } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) {
                indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
-       } else { /* should never be reached */
+       } else { /* Should never be reached */
                ret = -EINVAL;
                goto error_run_postdisable;
        }
@@ -640,13 +669,50 @@ error_run_postdisable:
 error_remove_inserted:
 
        if (insert_buffer)
-               list_del(&insert_buffer->buffer_list);
+               iio_buffer_deactivate(insert_buffer);
        indio_dev->active_scan_mask = old_mask;
        kfree(compound_mask);
 error_ret:
 
        return ret;
 }
+
+int iio_update_buffers(struct iio_dev *indio_dev,
+                      struct iio_buffer *insert_buffer,
+                      struct iio_buffer *remove_buffer)
+{
+       int ret;
+
+       if (insert_buffer == remove_buffer)
+               return 0;
+
+       mutex_lock(&indio_dev->info_exist_lock);
+       mutex_lock(&indio_dev->mlock);
+
+       if (insert_buffer && iio_buffer_is_active(insert_buffer))
+               insert_buffer = NULL;
+
+       if (remove_buffer && !iio_buffer_is_active(remove_buffer))
+               remove_buffer = NULL;
+
+       if (!insert_buffer && !remove_buffer) {
+               ret = 0;
+               goto out_unlock;
+       }
+
+       if (indio_dev->info == NULL) {
+               ret = -ENODEV;
+               goto out_unlock;
+       }
+
+       ret = __iio_update_buffers(indio_dev, insert_buffer, remove_buffer);
+
+out_unlock:
+       mutex_unlock(&indio_dev->mlock);
+       mutex_unlock(&indio_dev->info_exist_lock);
+
+       return ret;
+}
 EXPORT_SYMBOL_GPL(iio_update_buffers);
 
 ssize_t iio_buffer_store_enable(struct device *dev,
@@ -657,7 +723,6 @@ ssize_t iio_buffer_store_enable(struct device *dev,
        int ret;
        bool requested_state;
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct iio_buffer *pbuf = indio_dev->buffer;
        bool inlist;
 
        ret = strtobool(buf, &requested_state);
@@ -667,16 +732,16 @@ ssize_t iio_buffer_store_enable(struct device *dev,
        mutex_lock(&indio_dev->mlock);
 
        /* Find out if it is in the list */
-       inlist = iio_buffer_is_active(indio_dev, pbuf);
+       inlist = iio_buffer_is_active(indio_dev->buffer);
        /* Already in desired state */
        if (inlist == requested_state)
                goto done;
 
        if (requested_state)
-               ret = iio_update_buffers(indio_dev,
+               ret = __iio_update_buffers(indio_dev,
                                         indio_dev->buffer, NULL);
        else
-               ret = iio_update_buffers(indio_dev,
+               ret = __iio_update_buffers(indio_dev,
                                         NULL, indio_dev->buffer);
 
        if (ret < 0)
@@ -687,24 +752,6 @@ done:
 }
 EXPORT_SYMBOL(iio_buffer_store_enable);
 
-int iio_sw_buffer_preenable(struct iio_dev *indio_dev)
-{
-       struct iio_buffer *buffer;
-       unsigned bytes;
-       dev_dbg(&indio_dev->dev, "%s\n", __func__);
-
-       list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list)
-               if (buffer->access->set_bytes_per_datum) {
-                       bytes = iio_compute_scan_bytes(indio_dev,
-                                                      buffer->scan_mask,
-                                                      buffer->scan_timestamp);
-
-                       buffer->access->set_bytes_per_datum(buffer, bytes);
-               }
-       return 0;
-}
-EXPORT_SYMBOL(iio_sw_buffer_preenable);
-
 /**
  * iio_validate_scan_mask_onehot() - Validates that exactly one channel is selected
  * @indio_dev: the iio device
@@ -732,6 +779,7 @@ static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
 
 /**
  * iio_scan_mask_set() - set particular bit in the scan mask
+ * @indio_dev: the iio device
  * @buffer: the buffer whose scan mask we are interested in
  * @bit: the bit to be set.
  *
@@ -752,7 +800,7 @@ int iio_scan_mask_set(struct iio_dev *indio_dev,
        if (trialmask == NULL)
                return -ENOMEM;
        if (!indio_dev->masklength) {
-               WARN_ON("trying to set scanmask prior to registering buffer\n");
+               WARN_ON("Trying to set scanmask prior to registering buffer\n");
                goto err_invalid_mask;
        }
        bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
@@ -807,8 +855,8 @@ struct iio_demux_table {
        struct list_head l;
 };
 
-static unsigned char *iio_demux(struct iio_buffer *buffer,
-                                unsigned char *datain)
+static const void *iio_demux(struct iio_buffer *buffer,
+                                const void *datain)
 {
        struct iio_demux_table *t;
 
@@ -821,9 +869,9 @@ static unsigned char *iio_demux(struct iio_buffer *buffer,
        return buffer->demux_bounce;
 }
 
-static int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
+static int iio_push_to_buffer(struct iio_buffer *buffer, const void *data)
 {
-       unsigned char *dataout = iio_demux(buffer, data);
+       const void *dataout = iio_demux(buffer, data);
 
        return buffer->access->store_to(buffer, dataout);
 }
@@ -838,7 +886,7 @@ static void iio_buffer_demux_free(struct iio_buffer *buffer)
 }
 
 
-int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data)
+int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data)
 {
        int ret;
        struct iio_buffer *buf;
@@ -961,3 +1009,45 @@ error_clear_mux_table:
        return ret;
 }
 EXPORT_SYMBOL_GPL(iio_update_demux);
+
+/**
+ * iio_buffer_release() - Free a buffer's resources
+ * @ref: Pointer to the kref embedded in the iio_buffer struct
+ *
+ * This function is called when the last reference to the buffer has been
+ * dropped. It will typically free all resources allocated by the buffer. Do not
+ * call this function manually, always use iio_buffer_put() when done using a
+ * buffer.
+ */
+static void iio_buffer_release(struct kref *ref)
+{
+       struct iio_buffer *buffer = container_of(ref, struct iio_buffer, ref);
+
+       buffer->access->release(buffer);
+}
+
+/**
+ * iio_buffer_get() - Grab a reference to the buffer
+ * @buffer: The buffer to grab a reference for, may be NULL
+ *
+ * Returns the pointer to the buffer that was passed into the function.
+ */
+struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer)
+{
+       if (buffer)
+               kref_get(&buffer->ref);
+
+       return buffer;
+}
+EXPORT_SYMBOL_GPL(iio_buffer_get);
+
+/**
+ * iio_buffer_put() - Release the reference to the buffer
+ * @buffer: The buffer to release the reference for, may be NULL
+ */
+void iio_buffer_put(struct iio_buffer *buffer)
+{
+       if (buffer)
+               kref_put(&buffer->ref, iio_buffer_release);
+}
+EXPORT_SYMBOL_GPL(iio_buffer_put);
index f95c6979efd8f58fdf42e2a6d11a645b4191c17d..f7211576abe5d5385740df8276f0424d9c270574 100644 (file)
@@ -28,6 +28,7 @@
 #include "iio_core_trigger.h"
 #include <linux/iio/sysfs.h>
 #include <linux/iio/events.h>
+#include <linux/iio/buffer.h>
 
 /* IDA to assign each registered device a unique id */
 static DEFINE_IDA(iio_ida);
@@ -101,6 +102,7 @@ static const char * const iio_chan_info_postfix[] = {
        [IIO_CHAN_INFO_PHASE] = "phase",
        [IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
        [IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
+       [IIO_CHAN_INFO_INT_TIME] = "integration_time",
 };
 
 const struct iio_chan_spec
@@ -361,22 +363,20 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,
 }
 EXPORT_SYMBOL_GPL(iio_enum_write);
 
-static ssize_t iio_read_channel_info(struct device *dev,
-                                    struct device_attribute *attr,
-                                    char *buf)
+/**
+ * iio_format_value() - Formats a IIO value into its string representation
+ * @buf: The buffer to which the formated value gets written
+ * @type: One of the IIO_VAL_... constants. This decides how the val and val2
+ *        parameters are formatted.
+ * @val: First part of the value, exact meaning depends on the type parameter.
+ * @val2: Second part of the value, exact meaning depends on the type parameter.
+ */
+ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        unsigned long long tmp;
-       int val, val2;
        bool scale_db = false;
-       int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
-                                           &val, &val2, this_attr->address);
-
-       if (ret < 0)
-               return ret;
 
-       switch (ret) {
+       switch (type) {
        case IIO_VAL_INT:
                return sprintf(buf, "%d\n", val);
        case IIO_VAL_INT_PLUS_MICRO_DB:
@@ -408,6 +408,22 @@ static ssize_t iio_read_channel_info(struct device *dev,
        }
 }
 
+static ssize_t iio_read_channel_info(struct device *dev,
+                                    struct device_attribute *attr,
+                                    char *buf)
+{
+       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+       int val, val2;
+       int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
+                                           &val, &val2, this_attr->address);
+
+       if (ret < 0)
+               return ret;
+
+       return iio_format_value(buf, ret, val, val2);
+}
+
 /**
  * iio_str_to_fixpoint() - Parse a fixed-point number from a string
  * @str: The string to parse
@@ -516,14 +532,15 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                                                struct device_attribute *attr,
                                                const char *buf,
                                                size_t len),
-                          bool generic)
+                          enum iio_shared_by shared_by)
 {
-       int ret;
-       char *name_format, *full_postfix;
+       int ret = 0;
+       char *name_format = NULL;
+       char *full_postfix;
        sysfs_attr_init(&dev_attr->attr);
 
        /* Build up postfix of <extend_name>_<modifier>_postfix */
-       if (chan->modified && !generic) {
+       if (chan->modified && (shared_by == IIO_SEPARATE)) {
                if (chan->extend_name)
                        full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
                                                 iio_modifier_names[chan
@@ -544,53 +561,78 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                                                 chan->extend_name,
                                                 postfix);
        }
-       if (full_postfix == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       if (full_postfix == NULL)
+               return -ENOMEM;
 
        if (chan->differential) { /* Differential can not have modifier */
-               if (generic)
+               switch (shared_by) {
+               case IIO_SHARED_BY_ALL:
+                       name_format = kasprintf(GFP_KERNEL, "%s", full_postfix);
+                       break;
+               case IIO_SHARED_BY_DIR:
+                       name_format = kasprintf(GFP_KERNEL, "%s_%s",
+                                               iio_direction[chan->output],
+                                               full_postfix);
+                       break;
+               case IIO_SHARED_BY_TYPE:
                        name_format
                                = kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
                                            iio_direction[chan->output],
                                            iio_chan_type_name_spec[chan->type],
                                            iio_chan_type_name_spec[chan->type],
                                            full_postfix);
-               else if (chan->indexed)
+                       break;
+               case IIO_SEPARATE:
+                       if (!chan->indexed) {
+                               WARN_ON("Differential channels must be indexed\n");
+                               ret = -EINVAL;
+                               goto error_free_full_postfix;
+                       }
                        name_format
-                               = kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s",
+                               = kasprintf(GFP_KERNEL,
+                                           "%s_%s%d-%s%d_%s",
                                            iio_direction[chan->output],
                                            iio_chan_type_name_spec[chan->type],
                                            chan->channel,
                                            iio_chan_type_name_spec[chan->type],
                                            chan->channel2,
                                            full_postfix);
-               else {
-                       WARN_ON("Differential channels must be indexed\n");
-                       ret = -EINVAL;
-                       goto error_free_full_postfix;
+                       break;
                }
        } else { /* Single ended */
-               if (generic)
-                       name_format
-                               = kasprintf(GFP_KERNEL, "%s_%s_%s",
-                                           iio_direction[chan->output],
-                                           iio_chan_type_name_spec[chan->type],
-                                           full_postfix);
-               else if (chan->indexed)
-                       name_format
-                               = kasprintf(GFP_KERNEL, "%s_%s%d_%s",
-                                           iio_direction[chan->output],
-                                           iio_chan_type_name_spec[chan->type],
-                                           chan->channel,
-                                           full_postfix);
-               else
+               switch (shared_by) {
+               case IIO_SHARED_BY_ALL:
+                       name_format = kasprintf(GFP_KERNEL, "%s", full_postfix);
+                       break;
+               case IIO_SHARED_BY_DIR:
+                       name_format = kasprintf(GFP_KERNEL, "%s_%s",
+                                               iio_direction[chan->output],
+                                               full_postfix);
+                       break;
+               case IIO_SHARED_BY_TYPE:
                        name_format
                                = kasprintf(GFP_KERNEL, "%s_%s_%s",
                                            iio_direction[chan->output],
                                            iio_chan_type_name_spec[chan->type],
                                            full_postfix);
+                       break;
+
+               case IIO_SEPARATE:
+                       if (chan->indexed)
+                               name_format
+                                       = kasprintf(GFP_KERNEL, "%s_%s%d_%s",
+                                                   iio_direction[chan->output],
+                                                   iio_chan_type_name_spec[chan->type],
+                                                   chan->channel,
+                                                   full_postfix);
+                       else
+                               name_format
+                                       = kasprintf(GFP_KERNEL, "%s_%s_%s",
+                                                   iio_direction[chan->output],
+                                                   iio_chan_type_name_spec[chan->type],
+                                                   full_postfix);
+                       break;
+               }
        }
        if (name_format == NULL) {
                ret = -ENOMEM;
@@ -614,16 +656,11 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
                dev_attr->attr.mode |= S_IWUSR;
                dev_attr->store = writefunc;
        }
-       kfree(name_format);
-       kfree(full_postfix);
-
-       return 0;
-
 error_free_name_format:
        kfree(name_format);
 error_free_full_postfix:
        kfree(full_postfix);
-error_ret:
+
        return ret;
 }
 
@@ -642,7 +679,7 @@ int __iio_add_chan_devattr(const char *postfix,
                                                const char *buf,
                                                size_t len),
                           u64 mask,
-                          bool generic,
+                          enum iio_shared_by shared_by,
                           struct device *dev,
                           struct list_head *attr_list)
 {
@@ -656,7 +693,7 @@ int __iio_add_chan_devattr(const char *postfix,
        }
        ret = __iio_device_attr_init(&iio_attr->dev_attr,
                                     postfix, chan,
-                                    readfunc, writefunc, generic);
+                                    readfunc, writefunc, shared_by);
        if (ret)
                goto error_iio_dev_attr_free;
        iio_attr->c = chan;
@@ -664,7 +701,7 @@ int __iio_add_chan_devattr(const char *postfix,
        list_for_each_entry(t, attr_list, l)
                if (strcmp(t->dev_attr.attr.name,
                           iio_attr->dev_attr.attr.name) == 0) {
-                       if (!generic)
+                       if (shared_by == IIO_SEPARATE)
                                dev_err(dev, "tried to double register : %s\n",
                                        t->dev_attr.attr.name);
                        ret = -EBUSY;
@@ -682,46 +719,68 @@ error_ret:
        return ret;
 }
 
-static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
-                                       struct iio_chan_spec const *chan)
+static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
+                                        struct iio_chan_spec const *chan,
+                                        enum iio_shared_by shared_by,
+                                        const long *infomask)
 {
-       int ret, attrcount = 0;
-       int i;
-       const struct iio_chan_spec_ext_info *ext_info;
+       int i, ret, attrcount = 0;
 
-       if (chan->channel < 0)
-               return 0;
-       for_each_set_bit(i, &chan->info_mask_separate, sizeof(long)*8) {
-               ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
-                                            chan,
-                                            &iio_read_channel_info,
-                                            &iio_write_channel_info,
-                                            i,
-                                            0,
-                                            &indio_dev->dev,
-                                            &indio_dev->channel_attr_list);
-               if (ret < 0)
-                       goto error_ret;
-               attrcount++;
-       }
-       for_each_set_bit(i, &chan->info_mask_shared_by_type, sizeof(long)*8) {
+       for_each_set_bit(i, infomask, sizeof(infomask)*8) {
                ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
                                             chan,
                                             &iio_read_channel_info,
                                             &iio_write_channel_info,
                                             i,
-                                            1,
+                                            shared_by,
                                             &indio_dev->dev,
                                             &indio_dev->channel_attr_list);
-               if (ret == -EBUSY) {
-                       ret = 0;
+               if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE))
                        continue;
-               } else if (ret < 0) {
-                       goto error_ret;
-               }
+               else if (ret < 0)
+                       return ret;
                attrcount++;
        }
 
+       return attrcount;
+}
+
+static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
+                                       struct iio_chan_spec const *chan)
+{
+       int ret, attrcount = 0;
+       const struct iio_chan_spec_ext_info *ext_info;
+
+       if (chan->channel < 0)
+               return 0;
+       ret = iio_device_add_info_mask_type(indio_dev, chan,
+                                           IIO_SEPARATE,
+                                           &chan->info_mask_separate);
+       if (ret < 0)
+               return ret;
+       attrcount += ret;
+
+       ret = iio_device_add_info_mask_type(indio_dev, chan,
+                                           IIO_SHARED_BY_TYPE,
+                                           &chan->info_mask_shared_by_type);
+       if (ret < 0)
+               return ret;
+       attrcount += ret;
+
+       ret = iio_device_add_info_mask_type(indio_dev, chan,
+                                           IIO_SHARED_BY_DIR,
+                                           &chan->info_mask_shared_by_dir);
+       if (ret < 0)
+               return ret;
+       attrcount += ret;
+
+       ret = iio_device_add_info_mask_type(indio_dev, chan,
+                                           IIO_SHARED_BY_ALL,
+                                           &chan->info_mask_shared_by_all);
+       if (ret < 0)
+               return ret;
+       attrcount += ret;
+
        if (chan->ext_info) {
                unsigned int i = 0;
                for (ext_info = chan->ext_info; ext_info->name; ext_info++) {
@@ -740,22 +799,31 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
                                continue;
 
                        if (ret)
-                               goto error_ret;
+                               return ret;
 
                        attrcount++;
                }
        }
 
-       ret = attrcount;
-error_ret:
-       return ret;
+       return attrcount;
 }
 
-static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev,
-                                                struct iio_dev_attr *p)
+/**
+ * iio_free_chan_devattr_list() - Free a list of IIO device attributes
+ * @attr_list: List of IIO device attributes
+ *
+ * This function frees the memory allocated for each of the IIO device
+ * attributes in the list. Note: if you want to reuse the list after calling
+ * this function you have to reinitialize it using INIT_LIST_HEAD().
+ */
+void iio_free_chan_devattr_list(struct list_head *attr_list)
 {
-       kfree(p->dev_attr.attr.name);
-       kfree(p);
+       struct iio_dev_attr *p, *n;
+
+       list_for_each_entry_safe(p, n, attr_list, l) {
+               kfree(p->dev_attr.attr.name);
+               kfree(p);
+       }
 }
 
 static ssize_t iio_show_dev_name(struct device *dev,
@@ -771,7 +839,7 @@ static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);
 static int iio_device_register_sysfs(struct iio_dev *indio_dev)
 {
        int i, ret = 0, attrcount, attrn, attrcount_orig = 0;
-       struct iio_dev_attr *p, *n;
+       struct iio_dev_attr *p;
        struct attribute **attr;
 
        /* First count elements in any existing group */
@@ -824,11 +892,7 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev)
        return 0;
 
 error_clear_attrs:
-       list_for_each_entry_safe(p, n,
-                                &indio_dev->channel_attr_list, l) {
-               list_del(&p->l);
-               iio_device_remove_and_free_read_attr(indio_dev, p);
-       }
+       iio_free_chan_devattr_list(&indio_dev->channel_attr_list);
 
        return ret;
 }
@@ -836,12 +900,7 @@ error_clear_attrs:
 static void iio_device_unregister_sysfs(struct iio_dev *indio_dev)
 {
 
-       struct iio_dev_attr *p, *n;
-
-       list_for_each_entry_safe(p, n, &indio_dev->channel_attr_list, l) {
-               list_del(&p->l);
-               iio_device_remove_and_free_read_attr(indio_dev, p);
-       }
+       iio_free_chan_devattr_list(&indio_dev->channel_attr_list);
        kfree(indio_dev->chan_attr_group.attrs);
 }
 
@@ -853,6 +912,8 @@ static void iio_dev_release(struct device *device)
        iio_device_unregister_eventset(indio_dev);
        iio_device_unregister_sysfs(indio_dev);
 
+       iio_buffer_put(indio_dev->buffer);
+
        ida_simple_remove(&iio_ida, indio_dev->id);
        kfree(indio_dev);
 }
@@ -995,6 +1056,9 @@ static long iio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        int __user *ip = (int __user *)arg;
        int fd;
 
+       if (!indio_dev->info)
+               return -ENODEV;
+
        if (cmd == IIO_GET_EVENT_FD_IOCTL) {
                fd = iio_event_getfd(indio_dev);
                if (copy_to_user(ip, &fd, sizeof(fd)))
@@ -1091,6 +1155,10 @@ void iio_device_unregister(struct iio_dev *indio_dev)
        iio_disable_all_buffers(indio_dev);
 
        indio_dev->info = NULL;
+
+       iio_device_wakeup_eventset(indio_dev);
+       iio_buffer_wakeup_poll(indio_dev);
+
        mutex_unlock(&indio_dev->info_exist_lock);
 }
 EXPORT_SYMBOL(iio_device_unregister);
index 6be65ef5faa9b6e46716857af7ed67d8eb7ea004..dac15b9f9df8db9bf42518d1394875347b5fb0c6 100644 (file)
@@ -76,6 +76,9 @@ static unsigned int iio_event_poll(struct file *filep,
        struct iio_event_interface *ev_int = indio_dev->event_interface;
        unsigned int events = 0;
 
+       if (!indio_dev->info)
+               return -ENODEV;
+
        poll_wait(filep, &ev_int->wait, wait);
 
        spin_lock_irq(&ev_int->wait.lock);
@@ -96,6 +99,9 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
        unsigned int copied;
        int ret;
 
+       if (!indio_dev->info)
+               return -ENODEV;
+
        if (count < sizeof(struct iio_event_data))
                return -EINVAL;
 
@@ -107,9 +113,14 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
                }
                /* Blocking on device; waiting for something to be there */
                ret = wait_event_interruptible_locked_irq(ev_int->wait,
-                                       !kfifo_is_empty(&ev_int->det_events));
+                                       !kfifo_is_empty(&ev_int->det_events) ||
+                                       indio_dev->info == NULL);
                if (ret)
                        goto error_unlock;
+               if (indio_dev->info == NULL) {
+                       ret = -ENODEV;
+                       goto error_unlock;
+               }
                /* Single access device so no one else can get the data */
        }
 
@@ -166,7 +177,7 @@ int iio_event_getfd(struct iio_dev *indio_dev)
        iio_device_get(indio_dev);
 
        fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,
-                               indio_dev, O_RDONLY);
+                               indio_dev, O_RDONLY | O_CLOEXEC);
        if (fd < 0) {
                spin_lock_irq(&ev_int->wait.lock);
                __clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
@@ -190,6 +201,27 @@ static const char * const iio_ev_dir_text[] = {
        [IIO_EV_DIR_FALLING] = "falling"
 };
 
+static const char * const iio_ev_info_text[] = {
+       [IIO_EV_INFO_ENABLE] = "en",
+       [IIO_EV_INFO_VALUE] = "value",
+       [IIO_EV_INFO_HYSTERESIS] = "hysteresis",
+};
+
+static enum iio_event_direction iio_ev_attr_dir(struct iio_dev_attr *attr)
+{
+       return attr->c->event_spec[attr->address & 0xffff].dir;
+}
+
+static enum iio_event_type iio_ev_attr_type(struct iio_dev_attr *attr)
+{
+       return attr->c->event_spec[attr->address & 0xffff].type;
+}
+
+static enum iio_event_info iio_ev_attr_info(struct iio_dev_attr *attr)
+{
+       return (attr->address >> 16) & 0xffff;
+}
+
 static ssize_t iio_ev_state_store(struct device *dev,
                                  struct device_attribute *attr,
                                  const char *buf,
@@ -204,9 +236,14 @@ static ssize_t iio_ev_state_store(struct device *dev,
        if (ret < 0)
                return ret;
 
-       ret = indio_dev->info->write_event_config(indio_dev,
-                                                 this_attr->address,
-                                                 val);
+       if (indio_dev->info->write_event_config)
+               ret = indio_dev->info->write_event_config(indio_dev,
+                       this_attr->address, val);
+       else
+               ret = indio_dev->info->write_event_config_new(indio_dev,
+                       this_attr->c, iio_ev_attr_type(this_attr),
+                       iio_ev_attr_dir(this_attr), val);
+
        return (ret < 0) ? ret : len;
 }
 
@@ -216,9 +253,15 @@ static ssize_t iio_ev_state_show(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 val = indio_dev->info->read_event_config(indio_dev,
-                                                    this_attr->address);
+       int val;
 
+       if (indio_dev->info->read_event_config)
+               val = indio_dev->info->read_event_config(indio_dev,
+                       this_attr->address);
+       else
+               val = indio_dev->info->read_event_config_new(indio_dev,
+                       this_attr->c, iio_ev_attr_type(this_attr),
+                       iio_ev_attr_dir(this_attr));
        if (val < 0)
                return val;
        else
@@ -231,14 +274,24 @@ static ssize_t iio_ev_value_show(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 val, ret;
-
-       ret = indio_dev->info->read_event_value(indio_dev,
-                                               this_attr->address, &val);
-       if (ret < 0)
-               return ret;
+       int val, val2;
+       int ret;
 
-       return sprintf(buf, "%d\n", val);
+       if (indio_dev->info->read_event_value) {
+               ret = indio_dev->info->read_event_value(indio_dev,
+                       this_attr->address, &val);
+               if (ret < 0)
+                       return ret;
+               return sprintf(buf, "%d\n", val);
+       } else {
+               ret = indio_dev->info->read_event_value_new(indio_dev,
+                       this_attr->c, iio_ev_attr_type(this_attr),
+                       iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr),
+                       &val, &val2);
+               if (ret < 0)
+                       return ret;
+               return iio_format_value(buf, ret, val, val2);
+       }
 }
 
 static ssize_t iio_ev_value_store(struct device *dev,
@@ -248,25 +301,120 @@ static ssize_t iio_ev_value_store(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 val;
+       int val, val2;
        int ret;
 
-       if (!indio_dev->info->write_event_value)
+       if (!indio_dev->info->write_event_value &&
+               !indio_dev->info->write_event_value_new)
                return -EINVAL;
 
-       ret = kstrtoint(buf, 10, &val);
-       if (ret)
-               return ret;
-
-       ret = indio_dev->info->write_event_value(indio_dev, this_attr->address,
-                                                val);
+       if (indio_dev->info->write_event_value) {
+               ret = kstrtoint(buf, 10, &val);
+               if (ret)
+                       return ret;
+               ret = indio_dev->info->write_event_value(indio_dev,
+                       this_attr->address, val);
+       } else {
+               ret = iio_str_to_fixpoint(buf, 100000, &val, &val2);
+               if (ret)
+                       return ret;
+               ret = indio_dev->info->write_event_value_new(indio_dev,
+                       this_attr->c, iio_ev_attr_type(this_attr),
+                       iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr),
+                       val, val2);
+       }
        if (ret < 0)
                return ret;
 
        return len;
 }
 
-static int iio_device_add_event_sysfs(struct iio_dev *indio_dev,
+static int iio_device_add_event(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, unsigned int spec_index,
+       enum iio_event_type type, enum iio_event_direction dir,
+       enum iio_shared_by shared_by, const unsigned long *mask)
+{
+       ssize_t (*show)(struct device *, struct device_attribute *, char *);
+       ssize_t (*store)(struct device *, struct device_attribute *,
+               const char *, size_t);
+       unsigned int attrcount = 0;
+       unsigned int i;
+       char *postfix;
+       int ret;
+
+       for_each_set_bit(i, mask, sizeof(*mask)) {
+               postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
+                               iio_ev_type_text[type], iio_ev_dir_text[dir],
+                               iio_ev_info_text[i]);
+               if (postfix == NULL)
+                       return -ENOMEM;
+
+               if (i == IIO_EV_INFO_ENABLE) {
+                       show = iio_ev_state_show;
+                       store = iio_ev_state_store;
+               } else {
+                       show = iio_ev_value_show;
+                       store = iio_ev_value_store;
+               }
+
+               ret = __iio_add_chan_devattr(postfix, chan, show, store,
+                        (i << 16) | spec_index, shared_by, &indio_dev->dev,
+                       &indio_dev->event_interface->dev_attr_list);
+               kfree(postfix);
+
+               if (ret)
+                       return ret;
+
+               attrcount++;
+       }
+
+       return attrcount;
+}
+
+static int iio_device_add_event_sysfs_new(struct iio_dev *indio_dev,
+       struct iio_chan_spec const *chan)
+{
+       int ret = 0, i, attrcount = 0;
+       enum iio_event_direction dir;
+       enum iio_event_type type;
+
+       for (i = 0; i < chan->num_event_specs; i++) {
+               type = chan->event_spec[i].type;
+               dir = chan->event_spec[i].dir;
+
+               ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+                       IIO_SEPARATE, &chan->event_spec[i].mask_separate);
+               if (ret < 0)
+                       goto error_ret;
+               attrcount += ret;
+
+               ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+                       IIO_SHARED_BY_TYPE,
+                       &chan->event_spec[i].mask_shared_by_type);
+               if (ret < 0)
+                       goto error_ret;
+               attrcount += ret;
+
+               ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+                       IIO_SHARED_BY_DIR,
+                       &chan->event_spec[i].mask_shared_by_dir);
+               if (ret < 0)
+                       goto error_ret;
+               attrcount += ret;
+
+               ret = iio_device_add_event(indio_dev, chan, i, type, dir,
+                       IIO_SHARED_BY_ALL,
+                       &chan->event_spec[i].mask_shared_by_all);
+               if (ret < 0)
+                       goto error_ret;
+               attrcount += ret;
+       }
+       ret = attrcount;
+error_ret:
+       return ret;
+}
+
+static int iio_device_add_event_sysfs_old(struct iio_dev *indio_dev,
                                      struct iio_chan_spec const *chan)
 {
        int ret = 0, i, attrcount = 0;
@@ -339,15 +487,14 @@ error_ret:
        return ret;
 }
 
-static inline void __iio_remove_event_config_attrs(struct iio_dev *indio_dev)
+
+static int iio_device_add_event_sysfs(struct iio_dev *indio_dev,
+                                     struct iio_chan_spec const *chan)
 {
-       struct iio_dev_attr *p, *n;
-       list_for_each_entry_safe(p, n,
-                                &indio_dev->event_interface->
-                                dev_attr_list, l) {
-               kfree(p->dev_attr.attr.name);
-               kfree(p);
-       }
+       if (chan->event_mask)
+               return iio_device_add_event_sysfs_old(indio_dev, chan);
+       else
+               return iio_device_add_event_sysfs_new(indio_dev, chan);
 }
 
 static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev)
@@ -369,9 +516,12 @@ static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev)
 {
        int j;
 
-       for (j = 0; j < indio_dev->num_channels; j++)
+       for (j = 0; j < indio_dev->num_channels; j++) {
                if (indio_dev->channels[j].event_mask != 0)
                        return true;
+               if (indio_dev->channels[j].num_event_specs != 0)
+                       return true;
+       }
        return false;
 }
 
@@ -441,18 +591,32 @@ int iio_device_register_eventset(struct iio_dev *indio_dev)
        return 0;
 
 error_free_setup_event_lines:
-       __iio_remove_event_config_attrs(indio_dev);
+       iio_free_chan_devattr_list(&indio_dev->event_interface->dev_attr_list);
        kfree(indio_dev->event_interface);
 error_ret:
 
        return ret;
 }
 
+/**
+ * iio_device_wakeup_eventset - Wakes up the event waitqueue
+ * @indio_dev: The IIO device
+ *
+ * Wakes up the event waitqueue used for poll() and blocking read().
+ * Should usually be called when the device is unregistered.
+ */
+void iio_device_wakeup_eventset(struct iio_dev *indio_dev)
+{
+       if (indio_dev->event_interface == NULL)
+               return;
+       wake_up(&indio_dev->event_interface->wait);
+}
+
 void iio_device_unregister_eventset(struct iio_dev *indio_dev)
 {
        if (indio_dev->event_interface == NULL)
                return;
-       __iio_remove_event_config_attrs(indio_dev);
+       iio_free_chan_devattr_list(&indio_dev->event_interface->dev_attr_list);
        kfree(indio_dev->event_interface->group.attrs);
        kfree(indio_dev->event_interface);
 }
index 46c619b0d8c51141b6ee23aaf0a76d1facf525e7..d6f54930b34af49185f6fa76dd41372a5214bc35 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/iio/trigger_consumer.h>
 
 static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
-       .preenable = &iio_sw_buffer_preenable,
        .postenable = &iio_triggered_buffer_postenable,
        .predisable = &iio_triggered_buffer_predisable,
 };
@@ -47,14 +46,17 @@ int iio_triggered_buffer_setup(struct iio_dev *indio_dev,
        irqreturn_t (*pollfunc_th)(int irq, void *p),
        const struct iio_buffer_setup_ops *setup_ops)
 {
+       struct iio_buffer *buffer;
        int ret;
 
-       indio_dev->buffer = iio_kfifo_allocate(indio_dev);
-       if (!indio_dev->buffer) {
+       buffer = iio_kfifo_allocate(indio_dev);
+       if (!buffer) {
                ret = -ENOMEM;
                goto error_ret;
        }
 
+       iio_device_attach_buffer(indio_dev, buffer);
+
        indio_dev->pollfunc = iio_alloc_pollfunc(pollfunc_bh,
                                                 pollfunc_th,
                                                 IRQF_ONESHOT,
index a923c78d5cb48f40b2b661933b329f4ddb420c64..95c6fc81c2c78f2d57598995753e342302c3cb3a 100644 (file)
@@ -7,10 +7,12 @@
 #include <linux/mutex.h>
 #include <linux/iio/kfifo_buf.h>
 #include <linux/sched.h>
+#include <linux/poll.h>
 
 struct iio_kfifo {
        struct iio_buffer buffer;
        struct kfifo kf;
+       struct mutex user_lock;
        int update_needed;
 };
 
@@ -31,13 +33,18 @@ static int iio_request_update_kfifo(struct iio_buffer *r)
        int ret = 0;
        struct iio_kfifo *buf = iio_to_kfifo(r);
 
-       if (!buf->update_needed)
-               goto error_ret;
-       kfifo_free(&buf->kf);
-       ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum,
+       mutex_lock(&buf->user_lock);
+       if (buf->update_needed) {
+               kfifo_free(&buf->kf);
+               ret = __iio_allocate_kfifo(buf, buf->buffer.bytes_per_datum,
                                   buf->buffer.length);
+               buf->update_needed = false;
+       } else {
+               kfifo_reset_out(&buf->kf);
+       }
        r->stufftoread = false;
-error_ret:
+       mutex_unlock(&buf->user_lock);
+
        return ret;
 }
 
@@ -94,7 +101,7 @@ static int iio_set_length_kfifo(struct iio_buffer *r, int length)
 }
 
 static int iio_store_to_kfifo(struct iio_buffer *r,
-                             u8 *data)
+                             const void *data)
 {
        int ret;
        struct iio_kfifo *kf = iio_to_kfifo(r);
@@ -102,7 +109,7 @@ static int iio_store_to_kfifo(struct iio_buffer *r,
        if (ret != 1)
                return -EBUSY;
        r->stufftoread = true;
-       wake_up_interruptible(&r->pollq);
+       wake_up_interruptible_poll(&r->pollq, POLLIN | POLLRDNORM);
 
        return 0;
 }
@@ -113,12 +120,13 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r,
        int ret, copied;
        struct iio_kfifo *kf = iio_to_kfifo(r);
 
-       if (n < r->bytes_per_datum || r->bytes_per_datum == 0)
-               return -EINVAL;
+       if (mutex_lock_interruptible(&kf->user_lock))
+               return -ERESTARTSYS;
 
-       ret = kfifo_to_user(&kf->kf, buf, n, &copied);
-       if (ret < 0)
-               return ret;
+       if (!kfifo_initialized(&kf->kf) || n < kfifo_esize(&kf->kf))
+               ret = -EINVAL;
+       else
+               ret = kfifo_to_user(&kf->kf, buf, n, &copied);
 
        if (kfifo_is_empty(&kf->kf))
                r->stufftoread = false;
@@ -126,9 +134,22 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r,
        if (!kfifo_is_empty(&kf->kf))
                r->stufftoread = true;
 
+       mutex_unlock(&kf->user_lock);
+       if (ret < 0)
+               return ret;
+
        return copied;
 }
 
+static void iio_kfifo_buffer_release(struct iio_buffer *buffer)
+{
+       struct iio_kfifo *kf = iio_to_kfifo(buffer);
+
+       mutex_destroy(&kf->user_lock);
+       kfifo_free(&kf->kf);
+       kfree(kf);
+}
+
 static const struct iio_buffer_access_funcs kfifo_access_funcs = {
        .store_to = &iio_store_to_kfifo,
        .read_first_n = &iio_read_first_n_kfifo,
@@ -137,6 +158,7 @@ static const struct iio_buffer_access_funcs kfifo_access_funcs = {
        .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
        .get_length = &iio_get_length_kfifo,
        .set_length = &iio_set_length_kfifo,
+       .release = &iio_kfifo_buffer_release,
 };
 
 struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
@@ -151,13 +173,14 @@ struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev)
        kf->buffer.attrs = &iio_kfifo_attribute_group;
        kf->buffer.access = &kfifo_access_funcs;
        kf->buffer.length = 2;
+       mutex_init(&kf->user_lock);
        return &kf->buffer;
 }
 EXPORT_SYMBOL(iio_kfifo_allocate);
 
 void iio_kfifo_free(struct iio_buffer *r)
 {
-       kfree(iio_to_kfifo(r));
+       iio_buffer_put(r);
 }
 EXPORT_SYMBOL(iio_kfifo_free);
 
index bf9fa0d7aff9c26d0b4caf22bf25881de868c93d..f98c2b509254e2b8fdce8cd77db408f11b244495 100644 (file)
@@ -27,6 +27,29 @@ config APDS9300
         To compile this driver as a module, choose M here: the
         module will be called apds9300.
 
+config CM36651
+       depends on I2C
+       tristate "CM36651 driver"
+       help
+        Say Y here if you use cm36651.
+        This option enables proximity & RGB sensor using
+        Capella cm36651 device driver.
+
+        To compile this driver as a module, choose M here:
+        the module will be called cm36651.
+
+config GP2AP020A00F
+       tristate "Sharp GP2AP020A00F Proximity/ALS sensor"
+       depends on I2C
+       select IIO_BUFFER
+       select IIO_TRIGGERED_BUFFER
+       help
+         Say Y here if you have a Sharp GP2AP020A00F proximity/ALS combo-chip
+         hooked to an I2C bus.
+
+         To compile this driver as a module, choose M here: the
+         module will be called gp2ap020a00f.
+
 config HID_SENSOR_ALS
        depends on HID_SENSOR_HUB
        select IIO_BUFFER
@@ -55,6 +78,16 @@ config SENSORS_LM3533
          changes. The ALS-control output values can be set per zone for the
          three current output channels.
 
+config TCS3472
+       tristate "TAOS TCS3472 color light-to-digital converter"
+       depends on I2C
+       help
+        If you say yes here you get support for the TAOS TCS3472
+        family of color light-to-digital converters with IR filter.
+
+        This driver can also be built as a module.  If so, the module
+        will be called tcs3472.
+
 config SENSORS_TSL2563
        tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
        depends on I2C
@@ -65,6 +98,16 @@ config SENSORS_TSL2563
         This driver can also be built as a module.  If so, the module
         will be called tsl2563.
 
+config TSL4531
+       tristate "TAOS TSL4531 ambient light sensors"
+       depends on I2C
+       help
+        Say Y here if you want to build a driver for the TAOS TSL4531 family
+        of ambient light sensors with direct lux output.
+
+        To compile this driver as a module, choose M here: the
+        module will be called tsl4531.
+
 config VCNL4000
        tristate "VCNL4000 combined ALS and proximity sensor"
        depends on I2C
index 354ee9ab2379a92ba73a486d399e0b243c594ea1..daa327f39e04e71923e514320e081bab337633d2 100644 (file)
@@ -5,7 +5,11 @@
 # When adding new entries keep the list in alphabetical order
 obj-$(CONFIG_ADJD_S311)                += adjd_s311.o
 obj-$(CONFIG_APDS9300)         += apds9300.o
+obj-$(CONFIG_CM36651)          += cm36651.o
+obj-$(CONFIG_GP2AP020A00F)     += gp2ap020a00f.o
 obj-$(CONFIG_HID_SENSOR_ALS)   += hid-sensor-als.o
 obj-$(CONFIG_SENSORS_LM3533)   += lm3533-als.o
 obj-$(CONFIG_SENSORS_TSL2563)  += tsl2563.o
+obj-$(CONFIG_TCS3472)          += tcs3472.o
+obj-$(CONFIG_TSL4531)          += tsl4531.o
 obj-$(CONFIG_VCNL4000)         += vcnl4000.o
index 23cff798598aad0cf0f3078de05804d6a07541b5..83d15c5baf646cd61de0ecf4b87fa054b1df0f49 100644 (file)
@@ -114,43 +114,6 @@ static int adjd_s311_read_data(struct iio_dev *indio_dev, u8 reg, int *val)
        return 0;
 }
 
-static ssize_t adjd_s311_read_int_time(struct iio_dev *indio_dev,
-       uintptr_t private, const struct iio_chan_spec *chan, char *buf)
-{
-       struct adjd_s311_data *data = iio_priv(indio_dev);
-       s32 ret;
-
-       ret = i2c_smbus_read_word_data(data->client,
-               ADJD_S311_INT_REG(chan->address));
-       if (ret < 0)
-               return ret;
-
-       return sprintf(buf, "%d\n", ret & ADJD_S311_INT_MASK);
-}
-
-static ssize_t adjd_s311_write_int_time(struct iio_dev *indio_dev,
-        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
-        size_t len)
-{
-       struct adjd_s311_data *data = iio_priv(indio_dev);
-       unsigned long int_time;
-       int ret;
-
-       ret = kstrtoul(buf, 10, &int_time);
-       if (ret)
-               return ret;
-
-       if (int_time > ADJD_S311_INT_MASK)
-               return -EINVAL;
-
-       ret = i2c_smbus_write_word_data(data->client,
-               ADJD_S311_INT_REG(chan->address), int_time);
-       if (ret < 0)
-               return ret;
-
-       return len;
-}
-
 static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
 {
        struct iio_poll_func *pf = p;
@@ -175,10 +138,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
                len += 2;
        }
 
-       if (indio_dev->scan_timestamp)
-               *(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64)))
-                       = time_ns;
-       iio_push_to_buffers(indio_dev, (u8 *)data->buffer);
+       iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, time_ns);
 
 done:
        iio_trigger_notify_done(indio_dev->trig);
@@ -186,25 +146,16 @@ done:
        return IRQ_HANDLED;
 }
 
-static const struct iio_chan_spec_ext_info adjd_s311_ext_info[] = {
-       {
-               .name = "integration_time",
-               .read = adjd_s311_read_int_time,
-               .write = adjd_s311_write_int_time,
-       },
-       { }
-};
-
 #define ADJD_S311_CHANNEL(_color, _scan_idx) { \
        .type = IIO_INTENSITY, \
        .modified = 1, \
        .address = (IDX_##_color), \
        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
-               BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
+               BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \
+               BIT(IIO_CHAN_INFO_INT_TIME), \
        .channel2 = (IIO_MOD_LIGHT_##_color), \
        .scan_index = (_scan_idx), \
        .scan_type = IIO_ST('u', 10, 16, 0), \
-       .ext_info = adjd_s311_ext_info, \
 }
 
 static const struct iio_chan_spec adjd_s311_channels[] = {
@@ -236,6 +187,18 @@ static int adjd_s311_read_raw(struct iio_dev *indio_dev,
                        return ret;
                *val = ret & ADJD_S311_CAP_MASK;
                return IIO_VAL_INT;
+       case IIO_CHAN_INFO_INT_TIME:
+               ret = i2c_smbus_read_word_data(data->client,
+                       ADJD_S311_INT_REG(chan->address));
+               if (ret < 0)
+                       return ret;
+               *val = 0;
+               /*
+                * not documented, based on measurement:
+                * 4095 LSBs correspond to roughly 4 ms
+                */
+               *val2 = ret & ADJD_S311_INT_MASK;
+               return IIO_VAL_INT_PLUS_MICRO;
        }
        return -EINVAL;
 }
@@ -245,16 +208,20 @@ static int adjd_s311_write_raw(struct iio_dev *indio_dev,
                               int val, int val2, long mask)
 {
        struct adjd_s311_data *data = iio_priv(indio_dev);
-       int ret;
 
        switch (mask) {
        case IIO_CHAN_INFO_HARDWAREGAIN:
                if (val < 0 || val > ADJD_S311_CAP_MASK)
                        return -EINVAL;
 
-               ret = i2c_smbus_write_byte_data(data->client,
+               return i2c_smbus_write_byte_data(data->client,
                        ADJD_S311_CAP_REG(chan->address), val);
-               return ret;
+       case IIO_CHAN_INFO_INT_TIME:
+               if (val != 0 || val2 < 0 || val2 > ADJD_S311_INT_MASK)
+                       return -EINVAL;
+
+               return i2c_smbus_write_word_data(data->client,
+                       ADJD_S311_INT_REG(chan->address), val2);
        }
        return -EINVAL;
 }
index 66a58bda6dc893b96efb106be82296c275419c37..51097bbd59c94a584ed4ab060f0fda2729df80f6 100644 (file)
@@ -273,12 +273,14 @@ static int apds9300_read_raw(struct iio_dev *indio_dev,
        return ret;
 }
 
-static int apds9300_read_thresh(struct iio_dev *indio_dev, u64 event_code,
-               int *val)
+static int apds9300_read_thresh(struct iio_dev *indio_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)
 {
        struct apds9300_data *data = iio_priv(indio_dev);
 
-       switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+       switch (dir) {
        case IIO_EV_DIR_RISING:
                *val = data->thresh_hi;
                break;
@@ -289,17 +291,19 @@ static int apds9300_read_thresh(struct iio_dev *indio_dev, u64 event_code,
                return -EINVAL;
        }
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
-static int apds9300_write_thresh(struct iio_dev *indio_dev, u64 event_code,
-               int val)
+static int apds9300_write_thresh(struct iio_dev *indio_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)
 {
        struct apds9300_data *data = iio_priv(indio_dev);
        int ret;
 
        mutex_lock(&data->mutex);
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
+       if (dir == IIO_EV_DIR_RISING)
                ret = apds9300_set_thresh_hi(data, val);
        else
                ret = apds9300_set_thresh_low(data, val);
@@ -309,7 +313,9 @@ static int apds9300_write_thresh(struct iio_dev *indio_dev, u64 event_code,
 }
 
 static int apds9300_read_interrupt_config(struct iio_dev *indio_dev,
-               u64 event_code)
+               const struct iio_chan_spec *chan,
+               enum iio_event_type type,
+               enum iio_event_direction dir)
 {
        struct apds9300_data *data = iio_priv(indio_dev);
 
@@ -317,7 +323,8 @@ static int apds9300_read_interrupt_config(struct iio_dev *indio_dev,
 }
 
 static int apds9300_write_interrupt_config(struct iio_dev *indio_dev,
-               u64 event_code, int state)
+               const struct iio_chan_spec *chan, enum iio_event_type type,
+               enum iio_event_direction dir, int state)
 {
        struct apds9300_data *data = iio_priv(indio_dev);
        int ret;
@@ -337,10 +344,24 @@ static const struct iio_info apds9300_info_no_irq = {
 static const struct iio_info apds9300_info = {
        .driver_module          = THIS_MODULE,
        .read_raw               = apds9300_read_raw,
-       .read_event_value       = apds9300_read_thresh,
-       .write_event_value      = apds9300_write_thresh,
-       .read_event_config      = apds9300_read_interrupt_config,
-       .write_event_config     = apds9300_write_interrupt_config,
+       .read_event_value_new   = apds9300_read_thresh,
+       .write_event_value_new  = apds9300_write_thresh,
+       .read_event_config_new  = apds9300_read_interrupt_config,
+       .write_event_config_new = apds9300_write_interrupt_config,
+};
+
+static const struct iio_event_spec apds9300_event_spec[] = {
+       {
+               .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),
+       },
 };
 
 static const struct iio_chan_spec apds9300_channels[] = {
@@ -355,10 +376,8 @@ static const struct iio_chan_spec apds9300_channels[] = {
                .channel2 = IIO_MOD_LIGHT_BOTH,
                .indexed = true,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-               .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
-                                         IIO_EV_DIR_RISING) |
-                              IIO_EV_BIT(IIO_EV_TYPE_THRESH,
-                                         IIO_EV_DIR_FALLING)),
+               .event_spec = apds9300_event_spec,
+               .num_event_specs = ARRAY_SIZE(apds9300_event_spec),
        }, {
                .type = IIO_INTENSITY,
                .channel = 1,
diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c
new file mode 100644 (file)
index 0000000..21df571
--- /dev/null
@@ -0,0 +1,708 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General Public License version 2, as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/regulator/consumer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/events.h>
+
+/* Slave address 0x19 for PS of 7 bit addressing protocol for I2C */
+#define CM36651_I2C_ADDR_PS            0x19
+/* Alert Response Address */
+#define CM36651_ARA                    0x0C
+
+/* Ambient light sensor */
+#define CM36651_CS_CONF1               0x00
+#define CM36651_CS_CONF2               0x01
+#define CM36651_ALS_WH_M               0x02
+#define CM36651_ALS_WH_L               0x03
+#define CM36651_ALS_WL_M               0x04
+#define CM36651_ALS_WL_L               0x05
+#define CM36651_CS_CONF3               0x06
+#define CM36651_CS_CONF_REG_NUM                0x02
+
+/* Proximity sensor */
+#define CM36651_PS_CONF1               0x00
+#define CM36651_PS_THD                 0x01
+#define CM36651_PS_CANC                        0x02
+#define CM36651_PS_CONF2               0x03
+#define CM36651_PS_REG_NUM             0x04
+
+/* CS_CONF1 command code */
+#define CM36651_ALS_ENABLE             0x00
+#define CM36651_ALS_DISABLE            0x01
+#define CM36651_ALS_INT_EN             0x02
+#define CM36651_ALS_THRES              0x04
+
+/* CS_CONF2 command code */
+#define CM36651_CS_CONF2_DEFAULT_BIT   0x08
+
+/* CS_CONF3 channel integration time */
+#define CM36651_CS_IT1                 0x00 /* Integration time 80000 usec */
+#define CM36651_CS_IT2                 0x40 /* Integration time 160000 usec */
+#define CM36651_CS_IT3                 0x80 /* Integration time 320000 usec */
+#define CM36651_CS_IT4                 0xC0 /* Integration time 640000 usec */
+
+/* PS_CONF1 command code */
+#define CM36651_PS_ENABLE              0x00
+#define CM36651_PS_DISABLE             0x01
+#define CM36651_PS_INT_EN              0x02
+#define CM36651_PS_PERS2               0x04
+#define CM36651_PS_PERS3               0x08
+#define CM36651_PS_PERS4               0x0C
+
+/* PS_CONF1 command code: integration time */
+#define CM36651_PS_IT1                 0x00 /* Integration time 320 usec */
+#define CM36651_PS_IT2                 0x10 /* Integration time 420 usec */
+#define CM36651_PS_IT3                 0x20 /* Integration time 520 usec */
+#define CM36651_PS_IT4                 0x30 /* Integration time 640 usec */
+
+/* PS_CONF1 command code: duty ratio */
+#define CM36651_PS_DR1                 0x00 /* Duty ratio 1/80 */
+#define CM36651_PS_DR2                 0x40 /* Duty ratio 1/160 */
+#define CM36651_PS_DR3                 0x80 /* Duty ratio 1/320 */
+#define CM36651_PS_DR4                 0xC0 /* Duty ratio 1/640 */
+
+/* PS_THD command code */
+#define CM36651_PS_INITIAL_THD         0x05
+
+/* PS_CANC command code */
+#define CM36651_PS_CANC_DEFAULT                0x00
+
+/* PS_CONF2 command code */
+#define CM36651_PS_HYS1                        0x00
+#define CM36651_PS_HYS2                        0x01
+#define CM36651_PS_SMART_PERS_EN       0x02
+#define CM36651_PS_DIR_INT             0x04
+#define CM36651_PS_MS                  0x10
+
+#define CM36651_CS_COLOR_NUM           4
+
+#define CM36651_CLOSE_PROXIMITY                0x32
+#define CM36651_FAR_PROXIMITY                  0x33
+
+#define CM36651_CS_INT_TIME_AVAIL      "80000 160000 320000 640000"
+#define CM36651_PS_INT_TIME_AVAIL      "320 420 520 640"
+
+enum cm36651_operation_mode {
+       CM36651_LIGHT_EN,
+       CM36651_PROXIMITY_EN,
+       CM36651_PROXIMITY_EV_EN,
+};
+
+enum cm36651_light_channel_idx {
+       CM36651_LIGHT_CHANNEL_IDX_RED,
+       CM36651_LIGHT_CHANNEL_IDX_GREEN,
+       CM36651_LIGHT_CHANNEL_IDX_BLUE,
+       CM36651_LIGHT_CHANNEL_IDX_CLEAR,
+};
+
+enum cm36651_command {
+       CM36651_CMD_READ_RAW_LIGHT,
+       CM36651_CMD_READ_RAW_PROXIMITY,
+       CM36651_CMD_PROX_EV_EN,
+       CM36651_CMD_PROX_EV_DIS,
+};
+
+static const u8 cm36651_cs_reg[CM36651_CS_CONF_REG_NUM] = {
+       CM36651_CS_CONF1,
+       CM36651_CS_CONF2,
+};
+
+static const u8 cm36651_ps_reg[CM36651_PS_REG_NUM] = {
+       CM36651_PS_CONF1,
+       CM36651_PS_THD,
+       CM36651_PS_CANC,
+       CM36651_PS_CONF2,
+};
+
+struct cm36651_data {
+       const struct cm36651_platform_data *pdata;
+       struct i2c_client *client;
+       struct i2c_client *ps_client;
+       struct i2c_client *ara_client;
+       struct mutex lock;
+       struct regulator *vled_reg;
+       unsigned long flags;
+       int cs_int_time[CM36651_CS_COLOR_NUM];
+       int ps_int_time;
+       u8 cs_ctrl_regs[CM36651_CS_CONF_REG_NUM];
+       u8 ps_ctrl_regs[CM36651_PS_REG_NUM];
+       u16 color[CM36651_CS_COLOR_NUM];
+};
+
+static int cm36651_setup_reg(struct cm36651_data *cm36651)
+{
+       struct i2c_client *client = cm36651->client;
+       struct i2c_client *ps_client = cm36651->ps_client;
+       int i, ret;
+
+       /* CS initialization */
+       cm36651->cs_ctrl_regs[CM36651_CS_CONF1] = CM36651_ALS_ENABLE |
+                                                            CM36651_ALS_THRES;
+       cm36651->cs_ctrl_regs[CM36651_CS_CONF2] = CM36651_CS_CONF2_DEFAULT_BIT;
+
+       for (i = 0; i < CM36651_CS_CONF_REG_NUM; i++) {
+               ret = i2c_smbus_write_byte_data(client, cm36651_cs_reg[i],
+                                                    cm36651->cs_ctrl_regs[i]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       /* PS initialization */
+       cm36651->ps_ctrl_regs[CM36651_PS_CONF1] = CM36651_PS_ENABLE |
+                                                               CM36651_PS_IT2;
+       cm36651->ps_ctrl_regs[CM36651_PS_THD] = CM36651_PS_INITIAL_THD;
+       cm36651->ps_ctrl_regs[CM36651_PS_CANC] = CM36651_PS_CANC_DEFAULT;
+       cm36651->ps_ctrl_regs[CM36651_PS_CONF2] = CM36651_PS_HYS2 |
+                               CM36651_PS_DIR_INT | CM36651_PS_SMART_PERS_EN;
+
+       for (i = 0; i < CM36651_PS_REG_NUM; i++) {
+               ret = i2c_smbus_write_byte_data(ps_client, cm36651_ps_reg[i],
+                                                    cm36651->ps_ctrl_regs[i]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       /* Set shutdown mode */
+       ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
+                                                         CM36651_ALS_DISABLE);
+       if (ret < 0)
+               return ret;
+
+       ret = i2c_smbus_write_byte_data(cm36651->ps_client,
+                                        CM36651_PS_CONF1, CM36651_PS_DISABLE);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int cm36651_read_output(struct cm36651_data *cm36651,
+                               struct iio_chan_spec const *chan, int *val)
+{
+       struct i2c_client *client = cm36651->client;
+       int ret = -EINVAL;
+
+       switch (chan->type) {
+       case IIO_LIGHT:
+               *val = i2c_smbus_read_word_data(client, chan->address);
+               if (*val < 0)
+                       return ret;
+
+               ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
+                                                       CM36651_ALS_DISABLE);
+               if (ret < 0)
+                       return ret;
+
+               ret = IIO_VAL_INT;
+               break;
+       case IIO_PROXIMITY:
+               *val = i2c_smbus_read_byte(cm36651->ps_client);
+               if (*val < 0)
+                       return ret;
+
+               if (!test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
+                       ret = i2c_smbus_write_byte_data(cm36651->ps_client,
+                                       CM36651_PS_CONF1, CM36651_PS_DISABLE);
+                       if (ret < 0)
+                               return ret;
+               }
+
+               ret = IIO_VAL_INT;
+               break;
+       default:
+               break;
+       }
+
+       return ret;
+}
+
+static irqreturn_t cm36651_irq_handler(int irq, void *data)
+{
+       struct iio_dev *indio_dev = data;
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       struct i2c_client *client = cm36651->client;
+       int ev_dir, ret;
+       u64 ev_code;
+
+       /*
+        * The PS INT pin is an active low signal that PS INT move logic low
+        * when the object is detect. Once the MCU host received the PS INT
+        * "LOW" signal, the Host needs to read the data at Alert Response
+        * Address(ARA) to clear the PS INT signal. After clearing the PS
+        * INT pin, the PS INT signal toggles from low to high.
+        */
+       ret = i2c_smbus_read_byte(cm36651->ara_client);
+       if (ret < 0) {
+               dev_err(&client->dev,
+                               "%s: Data read failed: %d\n", __func__, ret);
+               return IRQ_HANDLED;
+       }
+       switch (ret) {
+       case CM36651_CLOSE_PROXIMITY:
+               ev_dir = IIO_EV_DIR_RISING;
+               break;
+       case CM36651_FAR_PROXIMITY:
+               ev_dir = IIO_EV_DIR_FALLING;
+               break;
+       default:
+               dev_err(&client->dev,
+                       "%s: Data read wrong: %d\n", __func__, ret);
+               return IRQ_HANDLED;
+       }
+
+       ev_code = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
+                               CM36651_CMD_READ_RAW_PROXIMITY,
+                               IIO_EV_TYPE_THRESH, ev_dir);
+
+       iio_push_event(indio_dev, ev_code, iio_get_time_ns());
+
+       return IRQ_HANDLED;
+}
+
+static int cm36651_set_operation_mode(struct cm36651_data *cm36651, int cmd)
+{
+       struct i2c_client *client = cm36651->client;
+       struct i2c_client *ps_client = cm36651->ps_client;
+       int ret = -EINVAL;
+
+       switch (cmd) {
+       case CM36651_CMD_READ_RAW_LIGHT:
+               ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
+                               cm36651->cs_ctrl_regs[CM36651_CS_CONF1]);
+               break;
+       case CM36651_CMD_READ_RAW_PROXIMITY:
+               if (test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags))
+                       return CM36651_PROXIMITY_EV_EN;
+
+               ret = i2c_smbus_write_byte_data(ps_client, CM36651_PS_CONF1,
+                               cm36651->ps_ctrl_regs[CM36651_PS_CONF1]);
+               break;
+       case CM36651_CMD_PROX_EV_EN:
+               if (test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
+                       dev_err(&client->dev,
+                               "Already proximity event enable state\n");
+                       return ret;
+               }
+               set_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
+
+               ret = i2c_smbus_write_byte_data(ps_client,
+                       cm36651_ps_reg[CM36651_PS_CONF1],
+                       CM36651_PS_INT_EN | CM36651_PS_PERS2 | CM36651_PS_IT2);
+
+               if (ret < 0) {
+                       dev_err(&client->dev, "Proximity enable event failed\n");
+                       return ret;
+               }
+               break;
+       case CM36651_CMD_PROX_EV_DIS:
+               if (!test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
+                       dev_err(&client->dev,
+                               "Already proximity event disable state\n");
+                       return ret;
+               }
+               clear_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
+               ret = i2c_smbus_write_byte_data(ps_client,
+                                       CM36651_PS_CONF1, CM36651_PS_DISABLE);
+               break;
+       }
+
+       if (ret < 0)
+               dev_err(&client->dev, "Write register failed\n");
+
+       return ret;
+}
+
+static int cm36651_read_channel(struct cm36651_data *cm36651,
+                               struct iio_chan_spec const *chan, int *val)
+{
+       struct i2c_client *client = cm36651->client;
+       int cmd, ret;
+
+       if (chan->type == IIO_LIGHT)
+               cmd = CM36651_CMD_READ_RAW_LIGHT;
+       else if (chan->type == IIO_PROXIMITY)
+               cmd = CM36651_CMD_READ_RAW_PROXIMITY;
+       else
+               return -EINVAL;
+
+       ret = cm36651_set_operation_mode(cm36651, cmd);
+       if (ret < 0) {
+               dev_err(&client->dev, "CM36651 set operation mode failed\n");
+               return ret;
+       }
+       /* Delay for work after enable operation */
+       msleep(50);
+       ret = cm36651_read_output(cm36651, chan, val);
+       if (ret < 0) {
+               dev_err(&client->dev, "CM36651 read output failed\n");
+               return ret;
+       }
+
+       return ret;
+}
+
+static int cm36651_read_int_time(struct cm36651_data *cm36651,
+                               struct iio_chan_spec const *chan, int *val)
+{
+       switch (chan->type) {
+       case IIO_LIGHT:
+               if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT1)
+                       *val = 80000;
+               else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT2)
+                       *val = 160000;
+               else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT3)
+                       *val = 320000;
+               else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT4)
+                       *val = 640000;
+               else
+                       return -EINVAL;
+               break;
+       case IIO_PROXIMITY:
+               if (cm36651->ps_int_time == CM36651_PS_IT1)
+                       *val = 320;
+               else if (cm36651->ps_int_time == CM36651_PS_IT2)
+                       *val = 420;
+               else if (cm36651->ps_int_time == CM36651_PS_IT3)
+                       *val = 520;
+               else if (cm36651->ps_int_time == CM36651_PS_IT4)
+                       *val = 640;
+               else
+                       return -EINVAL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return IIO_VAL_INT_PLUS_MICRO;
+}
+
+static int cm36651_write_int_time(struct cm36651_data *cm36651,
+                               struct iio_chan_spec const *chan, int val)
+{
+       struct i2c_client *client = cm36651->client;
+       struct i2c_client *ps_client = cm36651->ps_client;
+       int int_time, ret;
+
+       switch (chan->type) {
+       case IIO_LIGHT:
+               if (val == 80000)
+                       int_time = CM36651_CS_IT1;
+               else if (val == 160000)
+                       int_time = CM36651_CS_IT2;
+               else if (val == 320000)
+                       int_time = CM36651_CS_IT3;
+               else if (val == 640000)
+                       int_time = CM36651_CS_IT4;
+               else
+                       return -EINVAL;
+
+               ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF3,
+                                          int_time >> 2 * (chan->address));
+               if (ret < 0) {
+                       dev_err(&client->dev, "CS integration time write failed\n");
+                       return ret;
+               }
+               cm36651->cs_int_time[chan->address] = int_time;
+               break;
+       case IIO_PROXIMITY:
+               if (val == 320)
+                       int_time = CM36651_PS_IT1;
+               else if (val == 420)
+                       int_time = CM36651_PS_IT2;
+               else if (val == 520)
+                       int_time = CM36651_PS_IT3;
+               else if (val == 640)
+                       int_time = CM36651_PS_IT4;
+               else
+                       return -EINVAL;
+
+               ret = i2c_smbus_write_byte_data(ps_client,
+                                               CM36651_PS_CONF1, int_time);
+               if (ret < 0) {
+                       dev_err(&client->dev, "PS integration time write failed\n");
+                       return ret;
+               }
+               cm36651->ps_int_time = int_time;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+static int cm36651_read_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan,
+                           int *val, int *val2, long mask)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&cm36651->lock);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = cm36651_read_channel(cm36651, chan, val);
+               break;
+       case IIO_CHAN_INFO_INT_TIME:
+               ret = cm36651_read_int_time(cm36651, chan, val);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       mutex_unlock(&cm36651->lock);
+
+       return ret;
+}
+
+static int cm36651_write_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            int val, int val2, long mask)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       struct i2c_client *client = cm36651->client;
+       int ret = -EINVAL;
+
+       if (mask == IIO_CHAN_INFO_INT_TIME) {
+               ret = cm36651_write_int_time(cm36651, chan, val);
+               if (ret < 0)
+                       dev_err(&client->dev, "Integration time write failed\n");
+       }
+
+       return ret;
+}
+
+static int cm36651_read_prox_thresh(struct iio_dev *indio_dev,
+                                       u64 event_code, int *val)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+
+       *val = cm36651->ps_ctrl_regs[CM36651_PS_THD];
+
+       return 0;
+}
+
+static int cm36651_write_prox_thresh(struct iio_dev *indio_dev,
+                                       u64 event_code, int val)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       struct i2c_client *client = cm36651->client;
+       int ret;
+
+       if (val < 3 || val > 255)
+               return -EINVAL;
+
+       cm36651->ps_ctrl_regs[CM36651_PS_THD] = val;
+       ret = i2c_smbus_write_byte_data(cm36651->ps_client, CM36651_PS_THD,
+                                       cm36651->ps_ctrl_regs[CM36651_PS_THD]);
+
+       if (ret < 0) {
+               dev_err(&client->dev, "PS threshold write failed: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int cm36651_write_prox_event_config(struct iio_dev *indio_dev,
+                                       u64 event_code, int state)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       int cmd, ret = -EINVAL;
+
+       mutex_lock(&cm36651->lock);
+
+       cmd = state ? CM36651_CMD_PROX_EV_EN : CM36651_CMD_PROX_EV_DIS;
+       ret = cm36651_set_operation_mode(cm36651, cmd);
+
+       mutex_unlock(&cm36651->lock);
+
+       return ret;
+}
+
+static int cm36651_read_prox_event_config(struct iio_dev *indio_dev,
+                                                       u64 event_code)
+{
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+       int event_en;
+
+       mutex_lock(&cm36651->lock);
+
+       event_en = test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
+
+       mutex_unlock(&cm36651->lock);
+
+       return event_en;
+}
+
+#define CM36651_LIGHT_CHANNEL(_color, _idx) {          \
+       .type = IIO_LIGHT,                              \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
+                       BIT(IIO_CHAN_INFO_INT_TIME),    \
+       .address = _idx,                                \
+       .modified = 1,                                  \
+       .channel2 = IIO_MOD_LIGHT_##_color,             \
+}                                                      \
+
+static const struct iio_chan_spec cm36651_channels[] = {
+       {
+               .type = IIO_PROXIMITY,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                               BIT(IIO_CHAN_INFO_INT_TIME),
+               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER)
+       },
+       CM36651_LIGHT_CHANNEL(RED, CM36651_LIGHT_CHANNEL_IDX_RED),
+       CM36651_LIGHT_CHANNEL(GREEN, CM36651_LIGHT_CHANNEL_IDX_GREEN),
+       CM36651_LIGHT_CHANNEL(BLUE, CM36651_LIGHT_CHANNEL_IDX_BLUE),
+       CM36651_LIGHT_CHANNEL(CLEAR, CM36651_LIGHT_CHANNEL_IDX_CLEAR),
+};
+
+static IIO_CONST_ATTR(in_illuminance_integration_time_available,
+                                       CM36651_CS_INT_TIME_AVAIL);
+static IIO_CONST_ATTR(in_proximity_integration_time_available,
+                                       CM36651_PS_INT_TIME_AVAIL);
+
+static struct attribute *cm36651_attributes[] = {
+       &iio_const_attr_in_illuminance_integration_time_available.dev_attr.attr,
+       &iio_const_attr_in_proximity_integration_time_available.dev_attr.attr,
+       NULL,
+};
+
+static const struct attribute_group cm36651_attribute_group = {
+       .attrs = cm36651_attributes
+};
+
+static const struct iio_info cm36651_info = {
+       .driver_module          = THIS_MODULE,
+       .read_raw               = &cm36651_read_raw,
+       .write_raw              = &cm36651_write_raw,
+       .read_event_value       = &cm36651_read_prox_thresh,
+       .write_event_value      = &cm36651_write_prox_thresh,
+       .read_event_config      = &cm36651_read_prox_event_config,
+       .write_event_config     = &cm36651_write_prox_event_config,
+       .attrs                  = &cm36651_attribute_group,
+};
+
+static int cm36651_probe(struct i2c_client *client,
+                            const struct i2c_device_id *id)
+{
+       struct cm36651_data *cm36651;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*cm36651));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       cm36651 = iio_priv(indio_dev);
+
+       cm36651->vled_reg = devm_regulator_get(&client->dev, "vled");
+       if (IS_ERR(cm36651->vled_reg)) {
+               dev_err(&client->dev, "get regulator vled failed\n");
+               return PTR_ERR(cm36651->vled_reg);
+       }
+
+       ret = regulator_enable(cm36651->vled_reg);
+       if (ret) {
+               dev_err(&client->dev, "enable regulator vled failed\n");
+               return ret;
+       }
+
+       i2c_set_clientdata(client, indio_dev);
+
+       cm36651->client = client;
+       cm36651->ps_client = i2c_new_dummy(client->adapter,
+                                                    CM36651_I2C_ADDR_PS);
+       cm36651->ara_client = i2c_new_dummy(client->adapter, CM36651_ARA);
+       mutex_init(&cm36651->lock);
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->channels = cm36651_channels;
+       indio_dev->num_channels = ARRAY_SIZE(cm36651_channels);
+       indio_dev->info = &cm36651_info;
+       indio_dev->name = id->name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       ret = cm36651_setup_reg(cm36651);
+       if (ret) {
+               dev_err(&client->dev, "%s: register setup failed\n", __func__);
+               goto error_disable_reg;
+       }
+
+       ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler,
+                                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                                                       "cm36651", indio_dev);
+       if (ret) {
+               dev_err(&client->dev, "%s: request irq failed\n", __func__);
+               goto error_disable_reg;
+       }
+
+       ret = iio_device_register(indio_dev);
+       if (ret) {
+               dev_err(&client->dev, "%s: regist device failed\n", __func__);
+               goto error_free_irq;
+       }
+
+       return 0;
+
+error_free_irq:
+       free_irq(client->irq, indio_dev);
+error_disable_reg:
+       regulator_disable(cm36651->vled_reg);
+       return ret;
+}
+
+static int cm36651_remove(struct i2c_client *client)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct cm36651_data *cm36651 = iio_priv(indio_dev);
+
+       iio_device_unregister(indio_dev);
+       regulator_disable(cm36651->vled_reg);
+       free_irq(client->irq, indio_dev);
+
+       return 0;
+}
+
+static const struct i2c_device_id cm36651_id[] = {
+       { "cm36651", 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, cm36651_id);
+
+static const struct of_device_id cm36651_of_match[] = {
+       { .compatible = "capella,cm36651" },
+       { }
+};
+
+static struct i2c_driver cm36651_driver = {
+       .driver = {
+               .name   = "cm36651",
+               .of_match_table = of_match_ptr(cm36651_of_match),
+               .owner  = THIS_MODULE,
+       },
+       .probe          = cm36651_probe,
+       .remove         = cm36651_remove,
+       .id_table       = cm36651_id,
+};
+
+module_i2c_driver(cm36651_driver);
+
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_DESCRIPTION("CM36651 proximity/ambient light sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c
new file mode 100644 (file)
index 0000000..dc79835
--- /dev/null
@@ -0,0 +1,1654 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics Co., Ltd.
+ * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
+ *
+ * IIO features supported by the driver:
+ *
+ * Read-only raw channels:
+ *   - illiminance_clear [lux]
+ *   - illiminance_ir
+ *   - proximity
+ *
+ * Triggered buffer:
+ *   - illiminance_clear
+ *   - illiminance_ir
+ *   - proximity
+ *
+ * Events:
+ *   - illuminance_clear (rising and falling)
+ *   - proximity (rising and falling)
+ *     - both falling and rising thresholds for the proximity events
+ *       must be set to the values greater than 0.
+ *
+ * The driver supports triggered buffers for all the three
+ * channels as well as high and low threshold events for the
+ * illuminance_clear and proxmimity channels. Triggers
+ * can be enabled simultaneously with both illuminance_clear
+ * events. Proximity events cannot be enabled simultaneously
+ * with any triggers or illuminance events. Enabling/disabling
+ * one of the proximity events automatically enables/disables
+ * the other one.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irq_work.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/events.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define GP2A_I2C_NAME "gp2ap020a00f"
+
+/* Registers */
+#define GP2AP020A00F_OP_REG    0x00 /* Basic operations */
+#define GP2AP020A00F_ALS_REG   0x01 /* ALS related settings */
+#define GP2AP020A00F_PS_REG    0x02 /* PS related settings */
+#define GP2AP020A00F_LED_REG   0x03 /* LED reg */
+#define GP2AP020A00F_TL_L_REG  0x04 /* ALS: Threshold low LSB */
+#define GP2AP020A00F_TL_H_REG  0x05 /* ALS: Threshold low MSB */
+#define GP2AP020A00F_TH_L_REG  0x06 /* ALS: Threshold high LSB */
+#define GP2AP020A00F_TH_H_REG  0x07 /* ALS: Threshold high MSB */
+#define GP2AP020A00F_PL_L_REG  0x08 /* PS: Threshold low LSB */
+#define GP2AP020A00F_PL_H_REG  0x09 /* PS: Threshold low MSB */
+#define GP2AP020A00F_PH_L_REG  0x0a /* PS: Threshold high LSB */
+#define GP2AP020A00F_PH_H_REG  0x0b /* PS: Threshold high MSB */
+#define GP2AP020A00F_D0_L_REG  0x0c /* ALS result: Clear/Illuminance LSB */
+#define GP2AP020A00F_D0_H_REG  0x0d /* ALS result: Clear/Illuminance MSB */
+#define GP2AP020A00F_D1_L_REG  0x0e /* ALS result: IR LSB */
+#define GP2AP020A00F_D1_H_REG  0x0f /* ALS result: IR LSB */
+#define GP2AP020A00F_D2_L_REG  0x10 /* PS result LSB */
+#define GP2AP020A00F_D2_H_REG  0x11 /* PS result MSB */
+#define GP2AP020A00F_NUM_REGS  0x12 /* Number of registers */
+
+/* OP_REG bits */
+#define GP2AP020A00F_OP3_MASK          0x80 /* Software shutdown */
+#define GP2AP020A00F_OP3_SHUTDOWN      0x00
+#define GP2AP020A00F_OP3_OPERATION     0x80
+#define GP2AP020A00F_OP2_MASK          0x40 /* Auto shutdown/Continuous mode */
+#define GP2AP020A00F_OP2_AUTO_SHUTDOWN 0x00
+#define GP2AP020A00F_OP2_CONT_OPERATION        0x40
+#define GP2AP020A00F_OP_MASK           0x30 /* Operating mode selection  */
+#define GP2AP020A00F_OP_ALS_AND_PS     0x00
+#define GP2AP020A00F_OP_ALS            0x10
+#define GP2AP020A00F_OP_PS             0x20
+#define GP2AP020A00F_OP_DEBUG          0x30
+#define GP2AP020A00F_PROX_MASK         0x08 /* PS: detection/non-detection */
+#define GP2AP020A00F_PROX_NON_DETECT   0x00
+#define GP2AP020A00F_PROX_DETECT       0x08
+#define GP2AP020A00F_FLAG_P            0x04 /* PS: interrupt result  */
+#define GP2AP020A00F_FLAG_A            0x02 /* ALS: interrupt result  */
+#define GP2AP020A00F_TYPE_MASK         0x01 /* Output data type selection */
+#define GP2AP020A00F_TYPE_MANUAL_CALC  0x00
+#define GP2AP020A00F_TYPE_AUTO_CALC    0x01
+
+/* ALS_REG bits */
+#define GP2AP020A00F_PRST_MASK         0xc0 /* Number of measurement cycles */
+#define GP2AP020A00F_PRST_ONCE         0x00
+#define GP2AP020A00F_PRST_4_CYCLES     0x40
+#define GP2AP020A00F_PRST_8_CYCLES     0x80
+#define GP2AP020A00F_PRST_16_CYCLES    0xc0
+#define GP2AP020A00F_RES_A_MASK                0x38 /* ALS: Resolution */
+#define GP2AP020A00F_RES_A_800ms       0x00
+#define GP2AP020A00F_RES_A_400ms       0x08
+#define GP2AP020A00F_RES_A_200ms       0x10
+#define GP2AP020A00F_RES_A_100ms       0x18
+#define GP2AP020A00F_RES_A_25ms                0x20
+#define GP2AP020A00F_RES_A_6_25ms      0x28
+#define GP2AP020A00F_RES_A_1_56ms      0x30
+#define GP2AP020A00F_RES_A_0_39ms      0x38
+#define GP2AP020A00F_RANGE_A_MASK      0x07 /* ALS: Max measurable range */
+#define GP2AP020A00F_RANGE_A_x1                0x00
+#define GP2AP020A00F_RANGE_A_x2                0x01
+#define GP2AP020A00F_RANGE_A_x4                0x02
+#define GP2AP020A00F_RANGE_A_x8                0x03
+#define GP2AP020A00F_RANGE_A_x16       0x04
+#define GP2AP020A00F_RANGE_A_x32       0x05
+#define GP2AP020A00F_RANGE_A_x64       0x06
+#define GP2AP020A00F_RANGE_A_x128      0x07
+
+/* PS_REG bits */
+#define GP2AP020A00F_ALC_MASK          0x80 /* Auto light cancel */
+#define GP2AP020A00F_ALC_ON            0x80
+#define GP2AP020A00F_ALC_OFF           0x00
+#define GP2AP020A00F_INTTYPE_MASK      0x40 /* Interrupt type setting */
+#define GP2AP020A00F_INTTYPE_LEVEL     0x00
+#define GP2AP020A00F_INTTYPE_PULSE     0x40
+#define GP2AP020A00F_RES_P_MASK                0x38 /* PS: Resolution */
+#define GP2AP020A00F_RES_P_800ms_x2    0x00
+#define GP2AP020A00F_RES_P_400ms_x2    0x08
+#define GP2AP020A00F_RES_P_200ms_x2    0x10
+#define GP2AP020A00F_RES_P_100ms_x2    0x18
+#define GP2AP020A00F_RES_P_25ms_x2     0x20
+#define GP2AP020A00F_RES_P_6_25ms_x2   0x28
+#define GP2AP020A00F_RES_P_1_56ms_x2   0x30
+#define GP2AP020A00F_RES_P_0_39ms_x2   0x38
+#define GP2AP020A00F_RANGE_P_MASK      0x07 /* PS: Max measurable range */
+#define GP2AP020A00F_RANGE_P_x1                0x00
+#define GP2AP020A00F_RANGE_P_x2                0x01
+#define GP2AP020A00F_RANGE_P_x4                0x02
+#define GP2AP020A00F_RANGE_P_x8                0x03
+#define GP2AP020A00F_RANGE_P_x16       0x04
+#define GP2AP020A00F_RANGE_P_x32       0x05
+#define GP2AP020A00F_RANGE_P_x64       0x06
+#define GP2AP020A00F_RANGE_P_x128      0x07
+
+/* LED reg bits */
+#define GP2AP020A00F_INTVAL_MASK       0xc0 /* Intermittent operating */
+#define GP2AP020A00F_INTVAL_0          0x00
+#define GP2AP020A00F_INTVAL_4          0x40
+#define GP2AP020A00F_INTVAL_8          0x80
+#define GP2AP020A00F_INTVAL_16         0xc0
+#define GP2AP020A00F_IS_MASK           0x30 /* ILED drive peak current */
+#define GP2AP020A00F_IS_13_8mA         0x00
+#define GP2AP020A00F_IS_27_5mA         0x10
+#define GP2AP020A00F_IS_55mA           0x20
+#define GP2AP020A00F_IS_110mA          0x30
+#define GP2AP020A00F_PIN_MASK          0x0c /* INT terminal setting */
+#define GP2AP020A00F_PIN_ALS_OR_PS     0x00
+#define GP2AP020A00F_PIN_ALS           0x04
+#define GP2AP020A00F_PIN_PS            0x08
+#define GP2AP020A00F_PIN_PS_DETECT     0x0c
+#define GP2AP020A00F_FREQ_MASK         0x02 /* LED modulation frequency */
+#define GP2AP020A00F_FREQ_327_5kHz     0x00
+#define GP2AP020A00F_FREQ_81_8kHz      0x02
+#define GP2AP020A00F_RST               0x01 /* Software reset */
+
+#define GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR     0
+#define GP2AP020A00F_SCAN_MODE_LIGHT_IR                1
+#define GP2AP020A00F_SCAN_MODE_PROXIMITY       2
+#define GP2AP020A00F_CHAN_TIMESTAMP            3
+
+#define GP2AP020A00F_DATA_READY_TIMEOUT                msecs_to_jiffies(1000)
+#define GP2AP020A00F_DATA_REG(chan)            (GP2AP020A00F_D0_L_REG + \
+                                                       (chan) * 2)
+#define GP2AP020A00F_THRESH_REG(th_val_id)     (GP2AP020A00F_TL_L_REG + \
+                                                       (th_val_id) * 2)
+#define GP2AP020A00F_THRESH_VAL_ID(reg_addr)   ((reg_addr - 4) / 2)
+
+#define GP2AP020A00F_SUBTRACT_MODE     0
+#define GP2AP020A00F_ADD_MODE          1
+
+#define GP2AP020A00F_MAX_CHANNELS      3
+
+enum gp2ap020a00f_opmode {
+       GP2AP020A00F_OPMODE_READ_RAW_CLEAR,
+       GP2AP020A00F_OPMODE_READ_RAW_IR,
+       GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY,
+       GP2AP020A00F_OPMODE_ALS,
+       GP2AP020A00F_OPMODE_PS,
+       GP2AP020A00F_OPMODE_ALS_AND_PS,
+       GP2AP020A00F_OPMODE_PROX_DETECT,
+       GP2AP020A00F_OPMODE_SHUTDOWN,
+       GP2AP020A00F_NUM_OPMODES,
+};
+
+enum gp2ap020a00f_cmd {
+       GP2AP020A00F_CMD_READ_RAW_CLEAR,
+       GP2AP020A00F_CMD_READ_RAW_IR,
+       GP2AP020A00F_CMD_READ_RAW_PROXIMITY,
+       GP2AP020A00F_CMD_TRIGGER_CLEAR_EN,
+       GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS,
+       GP2AP020A00F_CMD_TRIGGER_IR_EN,
+       GP2AP020A00F_CMD_TRIGGER_IR_DIS,
+       GP2AP020A00F_CMD_TRIGGER_PROX_EN,
+       GP2AP020A00F_CMD_TRIGGER_PROX_DIS,
+       GP2AP020A00F_CMD_ALS_HIGH_EV_EN,
+       GP2AP020A00F_CMD_ALS_HIGH_EV_DIS,
+       GP2AP020A00F_CMD_ALS_LOW_EV_EN,
+       GP2AP020A00F_CMD_ALS_LOW_EV_DIS,
+       GP2AP020A00F_CMD_PROX_HIGH_EV_EN,
+       GP2AP020A00F_CMD_PROX_HIGH_EV_DIS,
+       GP2AP020A00F_CMD_PROX_LOW_EV_EN,
+       GP2AP020A00F_CMD_PROX_LOW_EV_DIS,
+};
+
+enum gp2ap020a00f_flags {
+       GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER,
+       GP2AP020A00F_FLAG_ALS_IR_TRIGGER,
+       GP2AP020A00F_FLAG_PROX_TRIGGER,
+       GP2AP020A00F_FLAG_PROX_RISING_EV,
+       GP2AP020A00F_FLAG_PROX_FALLING_EV,
+       GP2AP020A00F_FLAG_ALS_RISING_EV,
+       GP2AP020A00F_FLAG_ALS_FALLING_EV,
+       GP2AP020A00F_FLAG_LUX_MODE_HI,
+       GP2AP020A00F_FLAG_DATA_READY,
+};
+
+enum gp2ap020a00f_thresh_val_id {
+       GP2AP020A00F_THRESH_TL,
+       GP2AP020A00F_THRESH_TH,
+       GP2AP020A00F_THRESH_PL,
+       GP2AP020A00F_THRESH_PH,
+};
+
+struct gp2ap020a00f_data {
+       const struct gp2ap020a00f_platform_data *pdata;
+       struct i2c_client *client;
+       struct mutex lock;
+       char *buffer;
+       struct regulator *vled_reg;
+       unsigned long flags;
+       enum gp2ap020a00f_opmode cur_opmode;
+       struct iio_trigger *trig;
+       struct regmap *regmap;
+       unsigned int thresh_val[4];
+       u8 debug_reg_addr;
+       struct irq_work work;
+       wait_queue_head_t data_ready_queue;
+};
+
+static const u8 gp2ap020a00f_reg_init_tab[] = {
+       [GP2AP020A00F_OP_REG] = GP2AP020A00F_OP3_SHUTDOWN,
+       [GP2AP020A00F_ALS_REG] = GP2AP020A00F_RES_A_25ms |
+                                GP2AP020A00F_RANGE_A_x8,
+       [GP2AP020A00F_PS_REG] = GP2AP020A00F_ALC_ON |
+                               GP2AP020A00F_RES_P_1_56ms_x2 |
+                               GP2AP020A00F_RANGE_P_x4,
+       [GP2AP020A00F_LED_REG] = GP2AP020A00F_INTVAL_0 |
+                                GP2AP020A00F_IS_110mA |
+                                GP2AP020A00F_FREQ_327_5kHz,
+       [GP2AP020A00F_TL_L_REG] = 0,
+       [GP2AP020A00F_TL_H_REG] = 0,
+       [GP2AP020A00F_TH_L_REG] = 0,
+       [GP2AP020A00F_TH_H_REG] = 0,
+       [GP2AP020A00F_PL_L_REG] = 0,
+       [GP2AP020A00F_PL_H_REG] = 0,
+       [GP2AP020A00F_PH_L_REG] = 0,
+       [GP2AP020A00F_PH_H_REG] = 0,
+};
+
+static bool gp2ap020a00f_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case GP2AP020A00F_OP_REG:
+       case GP2AP020A00F_D0_L_REG:
+       case GP2AP020A00F_D0_H_REG:
+       case GP2AP020A00F_D1_L_REG:
+       case GP2AP020A00F_D1_H_REG:
+       case GP2AP020A00F_D2_L_REG:
+       case GP2AP020A00F_D2_H_REG:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static const struct regmap_config gp2ap020a00f_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+
+       .max_register = GP2AP020A00F_D2_H_REG,
+       .cache_type = REGCACHE_RBTREE,
+
+       .volatile_reg = gp2ap020a00f_is_volatile_reg,
+};
+
+static const struct gp2ap020a00f_mutable_config_regs {
+       u8 op_reg;
+       u8 als_reg;
+       u8 ps_reg;
+       u8 led_reg;
+} opmode_regs_settings[GP2AP020A00F_NUM_OPMODES] = {
+       [GP2AP020A00F_OPMODE_READ_RAW_CLEAR] = {
+               GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_AUTO_CALC,
+               GP2AP020A00F_PRST_ONCE,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_ALS
+       },
+       [GP2AP020A00F_OPMODE_READ_RAW_IR] = {
+               GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_MANUAL_CALC,
+               GP2AP020A00F_PRST_ONCE,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_ALS
+       },
+       [GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY] = {
+               GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_MANUAL_CALC,
+               GP2AP020A00F_PRST_ONCE,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_PS
+       },
+       [GP2AP020A00F_OPMODE_PROX_DETECT] = {
+               GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_MANUAL_CALC,
+               GP2AP020A00F_PRST_4_CYCLES,
+               GP2AP020A00F_INTTYPE_PULSE,
+               GP2AP020A00F_PIN_PS_DETECT
+       },
+       [GP2AP020A00F_OPMODE_ALS] = {
+               GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_AUTO_CALC,
+               GP2AP020A00F_PRST_ONCE,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_ALS
+       },
+       [GP2AP020A00F_OPMODE_PS] = {
+               GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_MANUAL_CALC,
+               GP2AP020A00F_PRST_4_CYCLES,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_PS
+       },
+       [GP2AP020A00F_OPMODE_ALS_AND_PS] = {
+               GP2AP020A00F_OP_ALS_AND_PS
+               | GP2AP020A00F_OP2_CONT_OPERATION
+               | GP2AP020A00F_OP3_OPERATION
+               | GP2AP020A00F_TYPE_AUTO_CALC,
+               GP2AP020A00F_PRST_4_CYCLES,
+               GP2AP020A00F_INTTYPE_LEVEL,
+               GP2AP020A00F_PIN_ALS_OR_PS
+       },
+       [GP2AP020A00F_OPMODE_SHUTDOWN] = { GP2AP020A00F_OP3_SHUTDOWN, },
+};
+
+static int gp2ap020a00f_set_operation_mode(struct gp2ap020a00f_data *data,
+                                       enum gp2ap020a00f_opmode op)
+{
+       unsigned int op_reg_val;
+       int err;
+
+       if (op != GP2AP020A00F_OPMODE_SHUTDOWN) {
+               err = regmap_read(data->regmap, GP2AP020A00F_OP_REG,
+                                       &op_reg_val);
+               if (err < 0)
+                       return err;
+               /*
+                * Shutdown the device if the operation being executed entails
+                * mode transition.
+                */
+               if ((opmode_regs_settings[op].op_reg & GP2AP020A00F_OP_MASK) !=
+                   (op_reg_val & GP2AP020A00F_OP_MASK)) {
+                       /* set shutdown mode */
+                       err = regmap_update_bits(data->regmap,
+                               GP2AP020A00F_OP_REG, GP2AP020A00F_OP3_MASK,
+                               GP2AP020A00F_OP3_SHUTDOWN);
+                       if (err < 0)
+                               return err;
+               }
+
+               err = regmap_update_bits(data->regmap, GP2AP020A00F_ALS_REG,
+                       GP2AP020A00F_PRST_MASK, opmode_regs_settings[op]
+                                                               .als_reg);
+               if (err < 0)
+                       return err;
+
+               err = regmap_update_bits(data->regmap, GP2AP020A00F_PS_REG,
+                       GP2AP020A00F_INTTYPE_MASK, opmode_regs_settings[op]
+                                                               .ps_reg);
+               if (err < 0)
+                       return err;
+
+               err = regmap_update_bits(data->regmap, GP2AP020A00F_LED_REG,
+                       GP2AP020A00F_PIN_MASK, opmode_regs_settings[op]
+                                                               .led_reg);
+               if (err < 0)
+                       return err;
+       }
+
+       /* Set OP_REG and apply operation mode (power on / off) */
+       err = regmap_update_bits(data->regmap,
+                                GP2AP020A00F_OP_REG,
+                                GP2AP020A00F_OP_MASK | GP2AP020A00F_OP2_MASK |
+                                GP2AP020A00F_OP3_MASK | GP2AP020A00F_TYPE_MASK,
+                                opmode_regs_settings[op].op_reg);
+       if (err < 0)
+               return err;
+
+       data->cur_opmode = op;
+
+       return 0;
+}
+
+static bool gp2ap020a00f_als_enabled(struct gp2ap020a00f_data *data)
+{
+       return test_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags) ||
+              test_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags) ||
+              test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags) ||
+              test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
+}
+
+static bool gp2ap020a00f_prox_detect_enabled(struct gp2ap020a00f_data *data)
+{
+       return test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags) ||
+              test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
+}
+
+static int gp2ap020a00f_write_event_threshold(struct gp2ap020a00f_data *data,
+                               enum gp2ap020a00f_thresh_val_id th_val_id,
+                               bool enable)
+{
+       __le16 thresh_buf = 0;
+       unsigned int thresh_reg_val;
+
+       if (!enable)
+               thresh_reg_val = 0;
+       else if (test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags) &&
+                th_val_id != GP2AP020A00F_THRESH_PL &&
+                th_val_id != GP2AP020A00F_THRESH_PH)
+               /*
+                * For the high lux mode ALS threshold has to be scaled down
+                * to allow for proper comparison with the output value.
+                */
+               thresh_reg_val = data->thresh_val[th_val_id] / 16;
+       else
+               thresh_reg_val = data->thresh_val[th_val_id] > 16000 ?
+                                       16000 :
+                                       data->thresh_val[th_val_id];
+
+       thresh_buf = cpu_to_le16(thresh_reg_val);
+
+       return regmap_bulk_write(data->regmap,
+                                GP2AP020A00F_THRESH_REG(th_val_id),
+                                (u8 *)&thresh_buf, 2);
+}
+
+static int gp2ap020a00f_alter_opmode(struct gp2ap020a00f_data *data,
+                       enum gp2ap020a00f_opmode diff_mode, int add_sub)
+{
+       enum gp2ap020a00f_opmode new_mode;
+
+       if (diff_mode != GP2AP020A00F_OPMODE_ALS &&
+           diff_mode != GP2AP020A00F_OPMODE_PS)
+               return -EINVAL;
+
+       if (add_sub == GP2AP020A00F_ADD_MODE) {
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_SHUTDOWN)
+                       new_mode =  diff_mode;
+               else
+                       new_mode = GP2AP020A00F_OPMODE_ALS_AND_PS;
+       } else {
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_ALS_AND_PS)
+                       new_mode = (diff_mode == GP2AP020A00F_OPMODE_ALS) ?
+                                       GP2AP020A00F_OPMODE_PS :
+                                       GP2AP020A00F_OPMODE_ALS;
+               else
+                       new_mode = GP2AP020A00F_OPMODE_SHUTDOWN;
+       }
+
+       return gp2ap020a00f_set_operation_mode(data, new_mode);
+}
+
+static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
+                                       enum gp2ap020a00f_cmd cmd)
+{
+       int err = 0;
+
+       switch (cmd) {
+       case GP2AP020A00F_CMD_READ_RAW_CLEAR:
+               if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
+                       return -EBUSY;
+               err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_READ_RAW_CLEAR);
+               break;
+       case GP2AP020A00F_CMD_READ_RAW_IR:
+               if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
+                       return -EBUSY;
+               err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_READ_RAW_IR);
+               break;
+       case GP2AP020A00F_CMD_READ_RAW_PROXIMITY:
+               if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
+                       return -EBUSY;
+               err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_CLEAR_EN:
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
+                       return -EBUSY;
+               if (!gp2ap020a00f_als_enabled(data))
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_ADD_MODE);
+               set_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS:
+               clear_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
+               if (gp2ap020a00f_als_enabled(data))
+                       break;
+               err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_SUBTRACT_MODE);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_IR_EN:
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
+                       return -EBUSY;
+               if (!gp2ap020a00f_als_enabled(data))
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_ADD_MODE);
+               set_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_IR_DIS:
+               clear_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
+               if (gp2ap020a00f_als_enabled(data))
+                       break;
+               err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_SUBTRACT_MODE);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_PROX_EN:
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
+                       return -EBUSY;
+               err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_PS,
+                                               GP2AP020A00F_ADD_MODE);
+               set_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &data->flags);
+               break;
+       case GP2AP020A00F_CMD_TRIGGER_PROX_DIS:
+               clear_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &data->flags);
+               err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_PS,
+                                               GP2AP020A00F_SUBTRACT_MODE);
+               break;
+       case GP2AP020A00F_CMD_ALS_HIGH_EV_EN:
+               if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags))
+                       return 0;
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
+                       return -EBUSY;
+               if (!gp2ap020a00f_als_enabled(data)) {
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_ADD_MODE);
+                       if (err < 0)
+                               return err;
+               }
+               set_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags);
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TH, true);
+               break;
+       case GP2AP020A00F_CMD_ALS_HIGH_EV_DIS:
+               if (!test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags))
+                       return 0;
+               clear_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags);
+               if (!gp2ap020a00f_als_enabled(data)) {
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_SUBTRACT_MODE);
+                       if (err < 0)
+                               return err;
+               }
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TH, false);
+               break;
+       case GP2AP020A00F_CMD_ALS_LOW_EV_EN:
+               if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags))
+                       return 0;
+               if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
+                       return -EBUSY;
+               if (!gp2ap020a00f_als_enabled(data)) {
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_ADD_MODE);
+                       if (err < 0)
+                               return err;
+               }
+               set_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TL, true);
+               break;
+       case GP2AP020A00F_CMD_ALS_LOW_EV_DIS:
+               if (!test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags))
+                       return 0;
+               clear_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
+               if (!gp2ap020a00f_als_enabled(data)) {
+                       err = gp2ap020a00f_alter_opmode(data,
+                                               GP2AP020A00F_OPMODE_ALS,
+                                               GP2AP020A00F_SUBTRACT_MODE);
+                       if (err < 0)
+                               return err;
+               }
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TL, false);
+               break;
+       case GP2AP020A00F_CMD_PROX_HIGH_EV_EN:
+               if (test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags))
+                       return 0;
+               if (gp2ap020a00f_als_enabled(data) ||
+                   data->cur_opmode == GP2AP020A00F_OPMODE_PS)
+                       return -EBUSY;
+               if (!gp2ap020a00f_prox_detect_enabled(data)) {
+                       err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_PROX_DETECT);
+                       if (err < 0)
+                               return err;
+               }
+               set_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags);
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_PH, true);
+               break;
+       case GP2AP020A00F_CMD_PROX_HIGH_EV_DIS:
+               if (!test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags))
+                       return 0;
+               clear_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags);
+               err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_SHUTDOWN);
+               if (err < 0)
+                       return err;
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_PH, false);
+               break;
+       case GP2AP020A00F_CMD_PROX_LOW_EV_EN:
+               if (test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags))
+                       return 0;
+               if (gp2ap020a00f_als_enabled(data) ||
+                   data->cur_opmode == GP2AP020A00F_OPMODE_PS)
+                       return -EBUSY;
+               if (!gp2ap020a00f_prox_detect_enabled(data)) {
+                       err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_PROX_DETECT);
+                       if (err < 0)
+                               return err;
+               }
+               set_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_PL, true);
+               break;
+       case GP2AP020A00F_CMD_PROX_LOW_EV_DIS:
+               if (!test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags))
+                       return 0;
+               clear_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
+               err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_SHUTDOWN);
+               if (err < 0)
+                       return err;
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_PL, false);
+               break;
+       }
+
+       return err;
+}
+
+static int wait_conversion_complete_irq(struct gp2ap020a00f_data *data)
+{
+       int ret;
+
+       ret = wait_event_timeout(data->data_ready_queue,
+                                test_bit(GP2AP020A00F_FLAG_DATA_READY,
+                                         &data->flags),
+                                GP2AP020A00F_DATA_READY_TIMEOUT);
+       clear_bit(GP2AP020A00F_FLAG_DATA_READY, &data->flags);
+
+       return ret > 0 ? 0 : -ETIME;
+}
+
+static int gp2ap020a00f_read_output(struct gp2ap020a00f_data *data,
+                                       unsigned int output_reg, int *val)
+{
+       u8 reg_buf[2];
+       int err;
+
+       err = wait_conversion_complete_irq(data);
+       if (err < 0)
+               dev_dbg(&data->client->dev, "data ready timeout\n");
+
+       err = regmap_bulk_read(data->regmap, output_reg, reg_buf, 2);
+       if (err < 0)
+               return err;
+
+       *val = le16_to_cpup((__le16 *)reg_buf);
+
+       return err;
+}
+
+static bool gp2ap020a00f_adjust_lux_mode(struct gp2ap020a00f_data *data,
+                                int output_val)
+{
+       u8 new_range = 0xff;
+       int err;
+
+       if (!test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags)) {
+               if (output_val > 16000) {
+                       set_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags);
+                       new_range = GP2AP020A00F_RANGE_A_x128;
+               }
+       } else {
+               if (output_val < 1000) {
+                       clear_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags);
+                       new_range = GP2AP020A00F_RANGE_A_x8;
+               }
+       }
+
+       if (new_range != 0xff) {
+               /* Clear als threshold registers to avoid spurious
+                * events caused by lux mode transition.
+                */
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TH, false);
+               if (err < 0) {
+                       dev_err(&data->client->dev,
+                               "Clearing als threshold register failed.\n");
+                       return false;
+               }
+
+               err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TL, false);
+               if (err < 0) {
+                       dev_err(&data->client->dev,
+                               "Clearing als threshold register failed.\n");
+                       return false;
+               }
+
+               /* Change lux mode */
+               err = regmap_update_bits(data->regmap,
+                       GP2AP020A00F_OP_REG,
+                       GP2AP020A00F_OP3_MASK,
+                       GP2AP020A00F_OP3_SHUTDOWN);
+
+               if (err < 0) {
+                       dev_err(&data->client->dev,
+                               "Shutting down the device failed.\n");
+                       return false;
+               }
+
+               err = regmap_update_bits(data->regmap,
+                       GP2AP020A00F_ALS_REG,
+                       GP2AP020A00F_RANGE_A_MASK,
+                       new_range);
+
+               if (err < 0) {
+                       dev_err(&data->client->dev,
+                               "Adjusting device lux mode failed.\n");
+                       return false;
+               }
+
+               err = regmap_update_bits(data->regmap,
+                       GP2AP020A00F_OP_REG,
+                       GP2AP020A00F_OP3_MASK,
+                       GP2AP020A00F_OP3_OPERATION);
+
+               if (err < 0) {
+                       dev_err(&data->client->dev,
+                               "Powering up the device failed.\n");
+                       return false;
+               }
+
+               /* Adjust als threshold register values to the new lux mode */
+               if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags)) {
+                       err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TH, true);
+                       if (err < 0) {
+                               dev_err(&data->client->dev,
+                               "Adjusting als threshold value failed.\n");
+                               return false;
+                       }
+               }
+
+               if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags)) {
+                       err =  gp2ap020a00f_write_event_threshold(data,
+                                       GP2AP020A00F_THRESH_TL, true);
+                       if (err < 0) {
+                               dev_err(&data->client->dev,
+                               "Adjusting als threshold value failed.\n");
+                               return false;
+                       }
+               }
+
+               return true;
+       }
+
+       return false;
+}
+
+static void gp2ap020a00f_output_to_lux(struct gp2ap020a00f_data *data,
+                                               int *output_val)
+{
+       if (test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags))
+               *output_val *= 16;
+}
+
+static void gp2ap020a00f_iio_trigger_work(struct irq_work *work)
+{
+       struct gp2ap020a00f_data *data =
+               container_of(work, struct gp2ap020a00f_data, work);
+
+       iio_trigger_poll(data->trig, 0);
+}
+
+static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data)
+{
+       struct iio_dev *indio_dev = data;
+       struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
+       unsigned int op_reg_val;
+       int ret;
+
+       /* Read interrupt flags */
+       ret = regmap_read(priv->regmap, GP2AP020A00F_OP_REG, &op_reg_val);
+       if (ret < 0)
+               return IRQ_HANDLED;
+
+       if (gp2ap020a00f_prox_detect_enabled(priv)) {
+               if (op_reg_val & GP2AP020A00F_PROX_DETECT) {
+                       iio_push_event(indio_dev,
+                              IIO_UNMOD_EVENT_CODE(
+                                   IIO_PROXIMITY,
+                                   GP2AP020A00F_SCAN_MODE_PROXIMITY,
+                                   IIO_EV_TYPE_ROC,
+                                   IIO_EV_DIR_RISING),
+                              iio_get_time_ns());
+               } else {
+                       iio_push_event(indio_dev,
+                              IIO_UNMOD_EVENT_CODE(
+                                   IIO_PROXIMITY,
+                                   GP2AP020A00F_SCAN_MODE_PROXIMITY,
+                                   IIO_EV_TYPE_ROC,
+                                   IIO_EV_DIR_FALLING),
+                              iio_get_time_ns());
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data)
+{
+       struct iio_dev *indio_dev = data;
+       struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
+       u8 op_reg_flags, d0_reg_buf[2];
+       unsigned int output_val, op_reg_val;
+       int thresh_val_id, ret;
+
+       /* Read interrupt flags */
+       ret = regmap_read(priv->regmap, GP2AP020A00F_OP_REG,
+                                                       &op_reg_val);
+       if (ret < 0)
+               goto done;
+
+       op_reg_flags = op_reg_val & (GP2AP020A00F_FLAG_A | GP2AP020A00F_FLAG_P
+                                       | GP2AP020A00F_PROX_DETECT);
+
+       op_reg_val &= (~GP2AP020A00F_FLAG_A & ~GP2AP020A00F_FLAG_P
+                                       & ~GP2AP020A00F_PROX_DETECT);
+
+       /* Clear interrupt flags (if not in INTTYPE_PULSE mode) */
+       if (priv->cur_opmode != GP2AP020A00F_OPMODE_PROX_DETECT) {
+               ret = regmap_write(priv->regmap, GP2AP020A00F_OP_REG,
+                                                               op_reg_val);
+               if (ret < 0)
+                       goto done;
+       }
+
+       if (op_reg_flags & GP2AP020A00F_FLAG_A) {
+               /* Check D0 register to assess if the lux mode
+                * transition is required.
+                */
+               ret = regmap_bulk_read(priv->regmap, GP2AP020A00F_D0_L_REG,
+                                                       d0_reg_buf, 2);
+               if (ret < 0)
+                       goto done;
+
+               output_val = le16_to_cpup((__le16 *)d0_reg_buf);
+
+               if (gp2ap020a00f_adjust_lux_mode(priv, output_val))
+                       goto done;
+
+               gp2ap020a00f_output_to_lux(priv, &output_val);
+
+               /*
+                * We need to check output value to distinguish
+                * between high and low ambient light threshold event.
+                */
+               if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &priv->flags)) {
+                       thresh_val_id =
+                           GP2AP020A00F_THRESH_VAL_ID(GP2AP020A00F_TH_L_REG);
+                       if (output_val > priv->thresh_val[thresh_val_id])
+                               iio_push_event(indio_dev,
+                                      IIO_MOD_EVENT_CODE(
+                                           IIO_LIGHT,
+                                           GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR,
+                                           IIO_MOD_LIGHT_CLEAR,
+                                           IIO_EV_TYPE_THRESH,
+                                           IIO_EV_DIR_RISING),
+                                      iio_get_time_ns());
+               }
+
+               if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &priv->flags)) {
+                       thresh_val_id =
+                           GP2AP020A00F_THRESH_VAL_ID(GP2AP020A00F_TL_L_REG);
+                       if (output_val < priv->thresh_val[thresh_val_id])
+                               iio_push_event(indio_dev,
+                                      IIO_MOD_EVENT_CODE(
+                                           IIO_LIGHT,
+                                           GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR,
+                                           IIO_MOD_LIGHT_CLEAR,
+                                           IIO_EV_TYPE_THRESH,
+                                           IIO_EV_DIR_FALLING),
+                                      iio_get_time_ns());
+               }
+       }
+
+       if (priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_CLEAR ||
+           priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_IR ||
+           priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY) {
+               set_bit(GP2AP020A00F_FLAG_DATA_READY, &priv->flags);
+               wake_up(&priv->data_ready_queue);
+               goto done;
+       }
+
+       if (test_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &priv->flags) ||
+           test_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &priv->flags) ||
+           test_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &priv->flags))
+               /* This fires off the trigger. */
+               irq_work_queue(&priv->work);
+
+done:
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t gp2ap020a00f_trigger_handler(int irq, void *data)
+{
+       struct iio_poll_func *pf = data;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
+       size_t d_size = 0;
+       __le32 light_lux;
+       int i, out_val, ret;
+
+       for_each_set_bit(i, indio_dev->active_scan_mask,
+               indio_dev->masklength) {
+               ret = regmap_bulk_read(priv->regmap,
+                               GP2AP020A00F_DATA_REG(i),
+                               &priv->buffer[d_size], 2);
+               if (ret < 0)
+                       goto done;
+
+               if (i == GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR ||
+                   i == GP2AP020A00F_SCAN_MODE_LIGHT_IR) {
+                       out_val = le16_to_cpup((__le16 *)&priv->buffer[d_size]);
+                       gp2ap020a00f_output_to_lux(priv, &out_val);
+                       light_lux = cpu_to_le32(out_val);
+                       memcpy(&priv->buffer[d_size], (u8 *)&light_lux, 4);
+                       d_size += 4;
+               } else {
+                       d_size += 2;
+               }
+       }
+
+       iio_push_to_buffers_with_timestamp(indio_dev, priv->buffer,
+               pf->timestamp);
+done:
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+static u8 gp2ap020a00f_get_thresh_reg(const struct iio_chan_spec *chan,
+                                            enum iio_event_direction event_dir)
+{
+       switch (chan->type) {
+       case IIO_PROXIMITY:
+               if (event_dir == IIO_EV_DIR_RISING)
+                       return GP2AP020A00F_PH_L_REG;
+               else
+                       return GP2AP020A00F_PL_L_REG;
+       case IIO_LIGHT:
+               if (event_dir == IIO_EV_DIR_RISING)
+                       return GP2AP020A00F_TH_L_REG;
+               else
+                       return GP2AP020A00F_TL_L_REG;
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+static int gp2ap020a00f_write_event_val(struct iio_dev *indio_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)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       bool event_en = false;
+       u8 thresh_val_id;
+       u8 thresh_reg_l;
+       int err = 0;
+
+       mutex_lock(&data->lock);
+
+       thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir);
+       thresh_val_id = GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l);
+
+       if (thresh_val_id > GP2AP020A00F_THRESH_PH) {
+               err = -EINVAL;
+               goto error_unlock;
+       }
+
+       switch (thresh_reg_l) {
+       case GP2AP020A00F_TH_L_REG:
+               event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV,
+                                                       &data->flags);
+               break;
+       case GP2AP020A00F_TL_L_REG:
+               event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV,
+                                                       &data->flags);
+               break;
+       case GP2AP020A00F_PH_L_REG:
+               if (val == 0) {
+                       err = -EINVAL;
+                       goto error_unlock;
+               }
+               event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV,
+                                                       &data->flags);
+               break;
+       case GP2AP020A00F_PL_L_REG:
+               if (val == 0) {
+                       err = -EINVAL;
+                       goto error_unlock;
+               }
+               event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV,
+                                                       &data->flags);
+               break;
+       }
+
+       data->thresh_val[thresh_val_id] = val;
+       err =  gp2ap020a00f_write_event_threshold(data, thresh_val_id,
+                                                       event_en);
+error_unlock:
+       mutex_unlock(&data->lock);
+
+       return err;
+}
+
+static int gp2ap020a00f_read_event_val(struct iio_dev *indio_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)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       u8 thresh_reg_l;
+       int err = IIO_VAL_INT;
+
+       mutex_lock(&data->lock);
+
+       thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir);
+
+       if (thresh_reg_l > GP2AP020A00F_PH_L_REG) {
+               err = -EINVAL;
+               goto error_unlock;
+       }
+
+       *val = data->thresh_val[GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l)];
+
+error_unlock:
+       mutex_unlock(&data->lock);
+
+       return err;
+}
+
+static int gp2ap020a00f_write_prox_event_config(struct iio_dev *indio_dev,
+                                               int state)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       enum gp2ap020a00f_cmd cmd_high_ev, cmd_low_ev;
+       int err;
+
+       cmd_high_ev = state ? GP2AP020A00F_CMD_PROX_HIGH_EV_EN :
+                             GP2AP020A00F_CMD_PROX_HIGH_EV_DIS;
+       cmd_low_ev = state ? GP2AP020A00F_CMD_PROX_LOW_EV_EN :
+                            GP2AP020A00F_CMD_PROX_LOW_EV_DIS;
+
+       /*
+        * In order to enable proximity detection feature in the device
+        * both high and low threshold registers have to be written
+        * with different values, greater than zero.
+        */
+       if (state) {
+               if (data->thresh_val[GP2AP020A00F_THRESH_PL] == 0)
+                       return -EINVAL;
+
+               if (data->thresh_val[GP2AP020A00F_THRESH_PH] == 0)
+                       return -EINVAL;
+       }
+
+       err = gp2ap020a00f_exec_cmd(data, cmd_high_ev);
+       if (err < 0)
+               return err;
+
+       err = gp2ap020a00f_exec_cmd(data, cmd_low_ev);
+       if (err < 0)
+               return err;
+
+       free_irq(data->client->irq, indio_dev);
+
+       if (state)
+               err = request_threaded_irq(data->client->irq, NULL,
+                                          &gp2ap020a00f_prox_sensing_handler,
+                                          IRQF_TRIGGER_RISING |
+                                          IRQF_TRIGGER_FALLING |
+                                          IRQF_ONESHOT,
+                                          "gp2ap020a00f_prox_sensing",
+                                          indio_dev);
+       else {
+               err = request_threaded_irq(data->client->irq, NULL,
+                                          &gp2ap020a00f_thresh_event_handler,
+                                          IRQF_TRIGGER_FALLING |
+                                          IRQF_ONESHOT,
+                                          "gp2ap020a00f_thresh_event",
+                                          indio_dev);
+       }
+
+       return err;
+}
+
+static int gp2ap020a00f_write_event_config(struct iio_dev *indio_dev,
+                                          const struct iio_chan_spec *chan,
+                                          enum iio_event_type type,
+                                          enum iio_event_direction dir,
+                                          int state)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       enum gp2ap020a00f_cmd cmd;
+       int err;
+
+       mutex_lock(&data->lock);
+
+       switch (chan->type) {
+       case IIO_PROXIMITY:
+               err = gp2ap020a00f_write_prox_event_config(indio_dev, state);
+               break;
+       case IIO_LIGHT:
+               if (dir == IIO_EV_DIR_RISING) {
+                       cmd = state ? GP2AP020A00F_CMD_ALS_HIGH_EV_EN :
+                                     GP2AP020A00F_CMD_ALS_HIGH_EV_DIS;
+                       err = gp2ap020a00f_exec_cmd(data, cmd);
+               } else {
+                       cmd = state ? GP2AP020A00F_CMD_ALS_LOW_EV_EN :
+                                     GP2AP020A00F_CMD_ALS_LOW_EV_DIS;
+                       err = gp2ap020a00f_exec_cmd(data, cmd);
+               }
+               break;
+       default:
+               err = -EINVAL;
+       }
+
+       mutex_unlock(&data->lock);
+
+       return err;
+}
+
+static int gp2ap020a00f_read_event_config(struct iio_dev *indio_dev,
+                                          const struct iio_chan_spec *chan,
+                                          enum iio_event_type type,
+                                          enum iio_event_direction dir)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       int event_en = 0;
+
+       mutex_lock(&data->lock);
+
+       switch (chan->type) {
+       case IIO_PROXIMITY:
+               if (dir == IIO_EV_DIR_RISING)
+                       event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV,
+                                                               &data->flags);
+               else
+                       event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV,
+                                                               &data->flags);
+               break;
+       case IIO_LIGHT:
+               if (dir == IIO_EV_DIR_RISING)
+                       event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV,
+                                                               &data->flags);
+               else
+                       event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV,
+                                                               &data->flags);
+               break;
+       default:
+               event_en = -EINVAL;
+               break;
+       }
+
+       mutex_unlock(&data->lock);
+
+       return event_en;
+}
+
+static int gp2ap020a00f_read_channel(struct gp2ap020a00f_data *data,
+                               struct iio_chan_spec const *chan, int *val)
+{
+       enum gp2ap020a00f_cmd cmd;
+       int err;
+
+       switch (chan->scan_index) {
+       case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR:
+               cmd = GP2AP020A00F_CMD_READ_RAW_CLEAR;
+               break;
+       case GP2AP020A00F_SCAN_MODE_LIGHT_IR:
+               cmd = GP2AP020A00F_CMD_READ_RAW_IR;
+               break;
+       case GP2AP020A00F_SCAN_MODE_PROXIMITY:
+               cmd = GP2AP020A00F_CMD_READ_RAW_PROXIMITY;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       err = gp2ap020a00f_exec_cmd(data, cmd);
+       if (err < 0) {
+               dev_err(&data->client->dev,
+                       "gp2ap020a00f_exec_cmd failed\n");
+               goto error_ret;
+       }
+
+       err = gp2ap020a00f_read_output(data, chan->address, val);
+       if (err < 0)
+               dev_err(&data->client->dev,
+                       "gp2ap020a00f_read_output failed\n");
+
+       err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_SHUTDOWN);
+       if (err < 0)
+               dev_err(&data->client->dev,
+                       "Failed to shut down the device.\n");
+
+       if (cmd == GP2AP020A00F_CMD_READ_RAW_CLEAR ||
+           cmd == GP2AP020A00F_CMD_READ_RAW_IR)
+               gp2ap020a00f_output_to_lux(data, val);
+
+error_ret:
+       return err;
+}
+
+static int gp2ap020a00f_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val, int *val2,
+                          long mask)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       int err = -EINVAL;
+
+       mutex_lock(&data->lock);
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               if (iio_buffer_enabled(indio_dev)) {
+                       err = -EBUSY;
+                       goto error_unlock;
+               }
+
+               err = gp2ap020a00f_read_channel(data, chan, val);
+               break;
+       }
+
+error_unlock:
+       mutex_unlock(&data->lock);
+
+       return err < 0 ? err : IIO_VAL_INT;
+}
+
+static const struct iio_event_spec gp2ap020a00f_event_spec_light[] = {
+       {
+               .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),
+       },
+};
+
+static const struct iio_event_spec gp2ap020a00f_event_spec_prox[] = {
+       {
+               .type = IIO_EV_TYPE_ROC,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_ROC,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
+static const struct iio_chan_spec gp2ap020a00f_channels[] = {
+       {
+               .type = IIO_LIGHT,
+               .channel2 = IIO_MOD_LIGHT_CLEAR,
+               .modified = 1,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 24,
+                       .shift = 0,
+                       .storagebits = 32,
+                       .endianness = IIO_LE,
+               },
+               .scan_index = GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR,
+               .address = GP2AP020A00F_D0_L_REG,
+               .event_spec = gp2ap020a00f_event_spec_light,
+               .num_event_specs = ARRAY_SIZE(gp2ap020a00f_event_spec_light),
+       },
+       {
+               .type = IIO_LIGHT,
+               .channel2 = IIO_MOD_LIGHT_IR,
+               .modified = 1,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 24,
+                       .shift = 0,
+                       .storagebits = 32,
+                       .endianness = IIO_LE,
+               },
+               .scan_index = GP2AP020A00F_SCAN_MODE_LIGHT_IR,
+               .address = GP2AP020A00F_D1_L_REG,
+       },
+       {
+               .type = IIO_PROXIMITY,
+               .modified = 0,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 16,
+                       .shift = 0,
+                       .storagebits = 16,
+                       .endianness = IIO_LE,
+               },
+               .scan_index = GP2AP020A00F_SCAN_MODE_PROXIMITY,
+               .address = GP2AP020A00F_D2_L_REG,
+               .event_spec = gp2ap020a00f_event_spec_prox,
+               .num_event_specs = ARRAY_SIZE(gp2ap020a00f_event_spec_prox),
+       },
+       IIO_CHAN_SOFT_TIMESTAMP(GP2AP020A00F_CHAN_TIMESTAMP),
+};
+
+static const struct iio_info gp2ap020a00f_info = {
+       .read_raw = &gp2ap020a00f_read_raw,
+       .read_event_value_new = &gp2ap020a00f_read_event_val,
+       .read_event_config_new = &gp2ap020a00f_read_event_config,
+       .write_event_value_new = &gp2ap020a00f_write_event_val,
+       .write_event_config_new = &gp2ap020a00f_write_event_config,
+       .driver_module = THIS_MODULE,
+};
+
+static int gp2ap020a00f_buffer_postenable(struct iio_dev *indio_dev)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       int i, err = 0;
+
+       mutex_lock(&data->lock);
+
+       /*
+        * Enable triggers according to the scan_mask. Enabling either
+        * LIGHT_CLEAR or LIGHT_IR scan mode results in enabling ALS
+        * module in the device, which generates samples in both D0 (clear)
+        * and D1 (ir) registers. As the two registers are bound to the
+        * two separate IIO channels they are treated in the driver logic
+        * as if they were controlled independently.
+        */
+       for_each_set_bit(i, indio_dev->active_scan_mask,
+               indio_dev->masklength) {
+               switch (i) {
+               case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_CLEAR_EN);
+                       break;
+               case GP2AP020A00F_SCAN_MODE_LIGHT_IR:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_IR_EN);
+                       break;
+               case GP2AP020A00F_SCAN_MODE_PROXIMITY:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_PROX_EN);
+                       break;
+               }
+       }
+
+       if (err < 0)
+               goto error_unlock;
+
+       data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+       if (!data->buffer) {
+               err = -ENOMEM;
+               goto error_unlock;
+       }
+
+       err = iio_triggered_buffer_postenable(indio_dev);
+
+error_unlock:
+       mutex_unlock(&data->lock);
+
+       return err;
+}
+
+static int gp2ap020a00f_buffer_predisable(struct iio_dev *indio_dev)
+{
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       int i, err;
+
+       mutex_lock(&data->lock);
+
+       err = iio_triggered_buffer_predisable(indio_dev);
+       if (err < 0)
+               goto error_unlock;
+
+       for_each_set_bit(i, indio_dev->active_scan_mask,
+               indio_dev->masklength) {
+               switch (i) {
+               case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS);
+                       break;
+               case GP2AP020A00F_SCAN_MODE_LIGHT_IR:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_IR_DIS);
+                       break;
+               case GP2AP020A00F_SCAN_MODE_PROXIMITY:
+                       err = gp2ap020a00f_exec_cmd(data,
+                                       GP2AP020A00F_CMD_TRIGGER_PROX_DIS);
+                       break;
+               }
+       }
+
+       if (err == 0)
+               kfree(data->buffer);
+
+error_unlock:
+       mutex_unlock(&data->lock);
+
+       return err;
+}
+
+static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = {
+       .postenable = &gp2ap020a00f_buffer_postenable,
+       .predisable = &gp2ap020a00f_buffer_predisable,
+};
+
+static const struct iio_trigger_ops gp2ap020a00f_trigger_ops = {
+       .owner = THIS_MODULE,
+};
+
+static int gp2ap020a00f_probe(struct i2c_client *client,
+                               const struct i2c_device_id *id)
+{
+       struct gp2ap020a00f_data *data;
+       struct iio_dev *indio_dev;
+       struct regmap *regmap;
+       int err;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+
+       data->vled_reg = devm_regulator_get(&client->dev, "vled");
+       if (IS_ERR(data->vled_reg))
+               return PTR_ERR(data->vled_reg);
+
+       err = regulator_enable(data->vled_reg);
+       if (err)
+               return err;
+
+       regmap = devm_regmap_init_i2c(client, &gp2ap020a00f_regmap_config);
+       if (IS_ERR(regmap)) {
+               dev_err(&client->dev, "Regmap initialization failed.\n");
+               err = PTR_ERR(regmap);
+               goto error_regulator_disable;
+       }
+
+       /* Initialize device registers */
+       err = regmap_bulk_write(regmap, GP2AP020A00F_OP_REG,
+                       gp2ap020a00f_reg_init_tab,
+                       ARRAY_SIZE(gp2ap020a00f_reg_init_tab));
+
+       if (err < 0) {
+               dev_err(&client->dev, "Device initialization failed.\n");
+               goto error_regulator_disable;
+       }
+
+       i2c_set_clientdata(client, indio_dev);
+
+       data->client = client;
+       data->cur_opmode = GP2AP020A00F_OPMODE_SHUTDOWN;
+       data->regmap = regmap;
+       init_waitqueue_head(&data->data_ready_queue);
+
+       mutex_init(&data->lock);
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->channels = gp2ap020a00f_channels;
+       indio_dev->num_channels = ARRAY_SIZE(gp2ap020a00f_channels);
+       indio_dev->info = &gp2ap020a00f_info;
+       indio_dev->name = id->name;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       /* Allocate buffer */
+       err = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
+               &gp2ap020a00f_trigger_handler, &gp2ap020a00f_buffer_setup_ops);
+       if (err < 0)
+               goto error_regulator_disable;
+
+       /* Allocate trigger */
+       data->trig = devm_iio_trigger_alloc(&client->dev, "%s-trigger",
+                                                       indio_dev->name);
+       if (data->trig == NULL) {
+               err = -ENOMEM;
+               dev_err(&indio_dev->dev, "Failed to allocate iio trigger.\n");
+               goto error_uninit_buffer;
+       }
+
+       /* This needs to be requested here for read_raw calls to work. */
+       err = request_threaded_irq(client->irq, NULL,
+                                  &gp2ap020a00f_thresh_event_handler,
+                                  IRQF_TRIGGER_FALLING |
+                                  IRQF_ONESHOT,
+                                  "gp2ap020a00f_als_event",
+                                  indio_dev);
+       if (err < 0) {
+               dev_err(&client->dev, "Irq request failed.\n");
+               goto error_uninit_buffer;
+       }
+
+       data->trig->ops = &gp2ap020a00f_trigger_ops;
+       data->trig->dev.parent = &data->client->dev;
+
+       init_irq_work(&data->work, gp2ap020a00f_iio_trigger_work);
+
+       err = iio_trigger_register(data->trig);
+       if (err < 0) {
+               dev_err(&client->dev, "Failed to register iio trigger.\n");
+               goto error_free_irq;
+       }
+
+       err = iio_device_register(indio_dev);
+       if (err < 0)
+               goto error_trigger_unregister;
+
+       return 0;
+
+error_trigger_unregister:
+       iio_trigger_unregister(data->trig);
+error_free_irq:
+       free_irq(client->irq, indio_dev);
+error_uninit_buffer:
+       iio_triggered_buffer_cleanup(indio_dev);
+error_regulator_disable:
+       regulator_disable(data->vled_reg);
+
+       return err;
+}
+
+static int gp2ap020a00f_remove(struct i2c_client *client)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+       struct gp2ap020a00f_data *data = iio_priv(indio_dev);
+       int err;
+
+       err = gp2ap020a00f_set_operation_mode(data,
+                                       GP2AP020A00F_OPMODE_SHUTDOWN);
+       if (err < 0)
+               dev_err(&indio_dev->dev, "Failed to power off the device.\n");
+
+       iio_device_unregister(indio_dev);
+       iio_trigger_unregister(data->trig);
+       free_irq(client->irq, indio_dev);
+       iio_triggered_buffer_cleanup(indio_dev);
+       regulator_disable(data->vled_reg);
+
+       return 0;
+}
+
+static const struct i2c_device_id gp2ap020a00f_id[] = {
+       { GP2A_I2C_NAME, 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id gp2ap020a00f_of_match[] = {
+       { .compatible = "sharp,gp2ap020a00f" },
+       { }
+};
+#endif
+
+static struct i2c_driver gp2ap020a00f_driver = {
+       .driver = {
+               .name   = GP2A_I2C_NAME,
+               .of_match_table = of_match_ptr(gp2ap020a00f_of_match),
+               .owner  = THIS_MODULE,
+       },
+       .probe          = gp2ap020a00f_probe,
+       .remove         = gp2ap020a00f_remove,
+       .id_table       = gp2ap020a00f_id,
+};
+
+module_i2c_driver(gp2ap020a00f_driver);
+
+MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
+MODULE_DESCRIPTION("Sharp GP2AP020A00F Proximity/ALS sensor driver");
+MODULE_LICENSE("GPL v2");
index e59d00c3139c00c15f44e4ab14c844341d9663e5..fa6ae8cf89eaa9edfdfffe379939bc7cc8a491f0 100644 (file)
@@ -161,10 +161,11 @@ static const struct iio_info als_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+                                       int len)
 {
        dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+       iio_push_to_buffers(indio_dev, data);
 }
 
 /* Callback handler to send event after all samples are received and captured */
@@ -179,7 +180,7 @@ static int als_proc_event(struct hid_sensor_hub_device *hsdev,
                                als_state->common_attributes.data_ready);
        if (als_state->common_attributes.data_ready)
                hid_sensor_push_data(indio_dev,
-                               (u8 *)&als_state->illum,
+                               &als_state->illum,
                                sizeof(als_state->illum));
 
        return 0;
diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c
new file mode 100644 (file)
index 0000000..45df220
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * tcs3472.c - Support for TAOS TCS3472 color light-to-digital converter
+ *
+ * Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * Color light sensor with 16-bit channels for red, green, blue, clear);
+ * 7-bit I2C slave address 0x39 (TCS34721, TCS34723) or 0x29 (TCS34725,
+ * TCS34727)
+ *
+ * TODO: interrupt support, thresholds, wait time
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+
+#define TCS3472_DRV_NAME "tcs3472"
+
+#define TCS3472_COMMAND BIT(7)
+#define TCS3472_AUTO_INCR BIT(5)
+
+#define TCS3472_ENABLE (TCS3472_COMMAND | 0x00)
+#define TCS3472_ATIME (TCS3472_COMMAND | 0x01)
+#define TCS3472_WTIME (TCS3472_COMMAND | 0x03)
+#define TCS3472_AILT (TCS3472_COMMAND | 0x04)
+#define TCS3472_AIHT (TCS3472_COMMAND | 0x06)
+#define TCS3472_PERS (TCS3472_COMMAND | 0x0c)
+#define TCS3472_CONFIG (TCS3472_COMMAND | 0x0d)
+#define TCS3472_CONTROL (TCS3472_COMMAND | 0x0f)
+#define TCS3472_ID (TCS3472_COMMAND | 0x12)
+#define TCS3472_STATUS (TCS3472_COMMAND | 0x13)
+#define TCS3472_CDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x14)
+#define TCS3472_RDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x16)
+#define TCS3472_GDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x18)
+#define TCS3472_BDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x1a)
+
+#define TCS3472_STATUS_AVALID BIT(0)
+#define TCS3472_ENABLE_AEN BIT(1)
+#define TCS3472_ENABLE_PON BIT(0)
+#define TCS3472_CONTROL_AGAIN_MASK (BIT(0) | BIT(1))
+
+struct tcs3472_data {
+       struct i2c_client *client;
+       u8 enable;
+       u8 control;
+       u8 atime;
+       u16 buffer[8]; /* 4 16-bit channels + 64-bit timestamp */
+};
+
+#define TCS3472_CHANNEL(_color, _si, _addr) { \
+       .type = IIO_INTENSITY, \
+       .modified = 1, \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBSCALE) | \
+               BIT(IIO_CHAN_INFO_INT_TIME), \
+       .channel2 = IIO_MOD_LIGHT_##_color, \
+       .address = _addr, \
+       .scan_index = _si, \
+       .scan_type = IIO_ST('u', 16, 16, 0), \
+}
+
+static const int tcs3472_agains[] = { 1, 4, 16, 60 };
+
+static const struct iio_chan_spec tcs3472_channels[] = {
+       TCS3472_CHANNEL(CLEAR, 0, TCS3472_CDATA),
+       TCS3472_CHANNEL(RED, 1, TCS3472_RDATA),
+       TCS3472_CHANNEL(GREEN, 2, TCS3472_GDATA),
+       TCS3472_CHANNEL(BLUE, 3, TCS3472_BDATA),
+       IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
+static int tcs3472_req_data(struct tcs3472_data *data)
+{
+       int tries = 50;
+       int ret;
+
+       while (tries--) {
+               ret = i2c_smbus_read_byte_data(data->client, TCS3472_STATUS);
+               if (ret < 0)
+                       return ret;
+               if (ret & TCS3472_STATUS_AVALID)
+                       break;
+               msleep(20);
+       }
+
+       if (tries < 0) {
+               dev_err(&data->client->dev, "data not ready\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int tcs3472_read_raw(struct iio_dev *indio_dev,
+                          struct iio_chan_spec const *chan,
+                          int *val, int *val2, long mask)
+{
+       struct tcs3472_data *data = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = tcs3472_req_data(data);
+               if (ret < 0)
+                       return ret;
+               ret = i2c_smbus_read_word_data(data->client, chan->address);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_CALIBSCALE:
+               *val = tcs3472_agains[data->control &
+                       TCS3472_CONTROL_AGAIN_MASK];
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_INT_TIME:
+               *val = 0;
+               *val2 = (256 - data->atime) * 2400;
+               return IIO_VAL_INT_PLUS_MICRO;
+       }
+       return -EINVAL;
+}
+
+static int tcs3472_write_raw(struct iio_dev *indio_dev,
+                              struct iio_chan_spec const *chan,
+                              int val, int val2, long mask)
+{
+       struct tcs3472_data *data = iio_priv(indio_dev);
+       int i;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_CALIBSCALE:
+               if (val2 != 0)
+                       return -EINVAL;
+               for (i = 0; i < ARRAY_SIZE(tcs3472_agains); i++) {
+                       if (val == tcs3472_agains[i]) {
+                               data->control &= ~TCS3472_CONTROL_AGAIN_MASK;
+                               data->control |= i;
+                               return i2c_smbus_write_byte_data(
+                                       data->client, TCS3472_CONTROL,
+                                       data->control);
+                       }
+               }
+               return -EINVAL;
+       case IIO_CHAN_INFO_INT_TIME:
+               if (val != 0)
+                       return -EINVAL;
+               for (i = 0; i < 256; i++) {
+                       if (val2 == (256 - i) * 2400) {
+                               data->atime = i;
+                               return i2c_smbus_write_word_data(
+                                       data->client, TCS3472_ATIME,
+                                       data->atime);
+                       }
+
+               }
+               return -EINVAL;
+       }
+       return -EINVAL;
+}
+
+static irqreturn_t tcs3472_trigger_handler(int irq, void *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct tcs3472_data *data = iio_priv(indio_dev);
+       int len = 0;
+       int i, j = 0;
+
+       int ret = tcs3472_req_data(data);
+       if (ret < 0)
+               goto done;
+
+       for_each_set_bit(i, indio_dev->active_scan_mask,
+               indio_dev->masklength) {
+               ret = i2c_smbus_read_word_data(data->client,
+                       TCS3472_CDATA + 2*i);
+               if (ret < 0)
+                       goto done;
+
+               data->buffer[j++] = ret;
+               len += 2;
+       }
+
+       iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+               iio_get_time_ns());
+
+done:
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+static ssize_t tcs3472_show_int_time_available(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       size_t len = 0;
+       int i;
+
+       for (i = 1; i <= 256; i++)
+               len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06d ",
+                       2400 * i);
+
+       /* replace trailing space by newline */
+       buf[len - 1] = '\n';
+
+       return len;
+}
+
+static IIO_CONST_ATTR(calibscale_available, "1 4 16 60");
+static IIO_DEV_ATTR_INT_TIME_AVAIL(tcs3472_show_int_time_available);
+
+static struct attribute *tcs3472_attributes[] = {
+       &iio_const_attr_calibscale_available.dev_attr.attr,
+       &iio_dev_attr_integration_time_available.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group tcs3472_attribute_group = {
+       .attrs = tcs3472_attributes,
+};
+
+static const struct iio_info tcs3472_info = {
+       .read_raw = tcs3472_read_raw,
+       .write_raw = tcs3472_write_raw,
+       .attrs = &tcs3472_attribute_group,
+       .driver_module = THIS_MODULE,
+};
+
+static int tcs3472_probe(struct i2c_client *client,
+                          const struct i2c_device_id *id)
+{
+       struct tcs3472_data *data;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (indio_dev == NULL)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+       i2c_set_clientdata(client, indio_dev);
+       data->client = client;
+
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->info = &tcs3472_info;
+       indio_dev->name = TCS3472_DRV_NAME;
+       indio_dev->channels = tcs3472_channels;
+       indio_dev->num_channels = ARRAY_SIZE(tcs3472_channels);
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       ret = i2c_smbus_read_byte_data(data->client, TCS3472_ID);
+       if (ret < 0)
+               return ret;
+
+       if (ret == 0x44)
+               dev_info(&client->dev, "TCS34721/34725 found\n");
+       else if (ret == 0x4d)
+               dev_info(&client->dev, "TCS34723/34727 found\n");
+       else
+               return -ENODEV;
+
+       ret = i2c_smbus_read_byte_data(data->client, TCS3472_CONTROL);
+       if (ret < 0)
+               return ret;
+       data->control = ret;
+
+       ret = i2c_smbus_read_byte_data(data->client, TCS3472_ATIME);
+       if (ret < 0)
+               return ret;
+       data->atime = ret;
+
+       ret = i2c_smbus_read_byte_data(data->client, TCS3472_ENABLE);
+       if (ret < 0)
+               return ret;
+
+       /* enable device */
+       data->enable = ret | TCS3472_ENABLE_PON | TCS3472_ENABLE_AEN;
+       ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
+               data->enable);
+       if (ret < 0)
+               return ret;
+
+       ret = iio_triggered_buffer_setup(indio_dev, NULL,
+               tcs3472_trigger_handler, NULL);
+       if (ret < 0)
+               return ret;
+
+       ret = iio_device_register(indio_dev);
+       if (ret < 0)
+               goto buffer_cleanup;
+
+       return 0;
+
+buffer_cleanup:
+       iio_triggered_buffer_cleanup(indio_dev);
+       return ret;
+}
+
+static int tcs3472_powerdown(struct tcs3472_data *data)
+{
+       return i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
+               data->enable & ~(TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON));
+}
+
+static int tcs3472_remove(struct i2c_client *client)
+{
+       struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+       iio_device_unregister(indio_dev);
+       iio_triggered_buffer_cleanup(indio_dev);
+       tcs3472_powerdown(iio_priv(indio_dev));
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tcs3472_suspend(struct device *dev)
+{
+       struct tcs3472_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
+       return tcs3472_powerdown(data);
+}
+
+static int tcs3472_resume(struct device *dev)
+{
+       struct tcs3472_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
+       return i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
+               data->enable | (TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON));
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(tcs3472_pm_ops, tcs3472_suspend, tcs3472_resume);
+
+static const struct i2c_device_id tcs3472_id[] = {
+       { "tcs3472", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tcs3472_id);
+
+static struct i2c_driver tcs3472_driver = {
+       .driver = {
+               .name   = TCS3472_DRV_NAME,
+               .pm     = &tcs3472_pm_ops,
+               .owner  = THIS_MODULE,
+       },
+       .probe          = tcs3472_probe,
+       .remove         = tcs3472_remove,
+       .id_table       = tcs3472_id,
+};
+module_i2c_driver(tcs3472_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("TCS3472 color light sensors driver");
+MODULE_LICENSE("GPL");
index ebb962c5c323a025f9c9e1ef8cfb27f40f2ba8d5..5e5d9dea22c598016c225848333c1e31595c811f 100644 (file)
@@ -526,6 +526,20 @@ error_ret:
        return ret;
 }
 
+static const struct iio_event_spec tsl2563_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),
+       },
+};
+
 static const struct iio_chan_spec tsl2563_channels[] = {
        {
                .type = IIO_LIGHT,
@@ -538,10 +552,8 @@ static const struct iio_chan_spec tsl2563_channels[] = {
                .channel2 = IIO_MOD_LIGHT_BOTH,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                BIT(IIO_CHAN_INFO_CALIBSCALE),
-               .event_mask = (IIO_EV_BIT(IIO_EV_TYPE_THRESH,
-                                         IIO_EV_DIR_RISING) |
-                              IIO_EV_BIT(IIO_EV_TYPE_THRESH,
-                                         IIO_EV_DIR_FALLING)),
+               .event_spec = tsl2563_events,
+               .num_event_specs = ARRAY_SIZE(tsl2563_events),
        }, {
                .type = IIO_INTENSITY,
                .modified = 1,
@@ -552,12 +564,13 @@ static const struct iio_chan_spec tsl2563_channels[] = {
 };
 
 static int tsl2563_read_thresh(struct iio_dev *indio_dev,
-                              u64 event_code,
-                              int *val)
+       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 tsl2563_chip *chip = iio_priv(indio_dev);
 
-       switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+       switch (dir) {
        case IIO_EV_DIR_RISING:
                *val = chip->high_thres;
                break;
@@ -568,18 +581,19 @@ static int tsl2563_read_thresh(struct iio_dev *indio_dev,
                return -EINVAL;
        }
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
 static int tsl2563_write_thresh(struct iio_dev *indio_dev,
-                                 u64 event_code,
-                                 int val)
+       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 tsl2563_chip *chip = iio_priv(indio_dev);
        int ret;
        u8 address;
 
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
+       if (dir == IIO_EV_DIR_RISING)
                address = TSL2563_REG_HIGHLOW;
        else
                address = TSL2563_REG_LOWLOW;
@@ -591,7 +605,7 @@ static int tsl2563_write_thresh(struct iio_dev *indio_dev,
        ret = i2c_smbus_write_byte_data(chip->client,
                                        TSL2563_CMD | (address + 1),
                                        (val >> 8) & 0xFF);
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
+       if (dir == IIO_EV_DIR_RISING)
                chip->high_thres = val;
        else
                chip->low_thres = val;
@@ -620,8 +634,8 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private)
 }
 
 static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev,
-                                         u64 event_code,
-                                         int state)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, int state)
 {
        struct tsl2563_chip *chip = iio_priv(indio_dev);
        int ret = 0;
@@ -662,7 +676,8 @@ out:
 }
 
 static int tsl2563_read_interrupt_config(struct iio_dev *indio_dev,
-                                        u64 event_code)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir)
 {
        struct tsl2563_chip *chip = iio_priv(indio_dev);
        int ret;
@@ -687,10 +702,10 @@ static const struct iio_info tsl2563_info = {
        .driver_module = THIS_MODULE,
        .read_raw = &tsl2563_read_raw,
        .write_raw = &tsl2563_write_raw,
-       .read_event_value = &tsl2563_read_thresh,
-       .write_event_value = &tsl2563_write_thresh,
-       .read_event_config = &tsl2563_read_interrupt_config,
-       .write_event_config = &tsl2563_write_interrupt_config,
+       .read_event_value_new = &tsl2563_read_thresh,
+       .write_event_value_new = &tsl2563_write_thresh,
+       .read_event_config_new = &tsl2563_read_interrupt_config,
+       .write_event_config_new = &tsl2563_write_interrupt_config,
 };
 
 static int tsl2563_probe(struct i2c_client *client,
diff --git a/drivers/iio/light/tsl4531.c b/drivers/iio/light/tsl4531.c
new file mode 100644 (file)
index 0000000..a15006e
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * tsl4531.c - Support for TAOS TSL4531 ambient light sensor
+ *
+ * Copyright 2013 Peter Meerwald <pmeerw@pmeerw.net>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License.  See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * IIO driver for the TSL4531x family
+ *   TSL45311/TSL45313: 7-bit I2C slave address 0x39
+ *   TSL45315/TSL45317: 7-bit I2C slave address 0x29
+ *
+ * TODO: single cycle measurement
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+
+#define TSL4531_DRV_NAME "tsl4531"
+
+#define TCS3472_COMMAND BIT(7)
+
+#define TSL4531_CONTROL (TCS3472_COMMAND | 0x00)
+#define TSL4531_CONFIG (TCS3472_COMMAND | 0x01)
+#define TSL4531_DATA (TCS3472_COMMAND | 0x04)
+#define TSL4531_ID (TCS3472_COMMAND | 0x0a)
+
+/* operating modes in control register */
+#define TSL4531_MODE_POWERDOWN 0x00
+#define TSL4531_MODE_SINGLE_ADC 0x02
+#define TSL4531_MODE_NORMAL 0x03
+
+/* integration time control in config register */
+#define TSL4531_TCNTRL_400MS 0x00
+#define TSL4531_TCNTRL_200MS 0x01
+#define TSL4531_TCNTRL_100MS 0x02
+
+/* part number in id register */
+#define TSL45311_ID 0x8
+#define TSL45313_ID 0x9
+#define TSL45315_ID 0xa
+#define TSL45317_ID 0xb
+#define TSL4531_ID_SHIFT 4
+
+struct tsl4531_data {
+       struct i2c_client *client;
+       struct mutex lock;
+       int int_time;
+};
+
+static IIO_CONST_ATTR_INT_TIME_AVAIL("0.1 0.2 0.4");
+
+static struct attribute *tsl4531_attributes[] = {
+       &iio_const_attr_integration_time_available.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group tsl4531_attribute_group = {
+       .attrs = tsl4531_attributes,
+};
+
+static const struct iio_chan_spec tsl4531_channels[] = {
+       {
+               .type = IIO_LIGHT,
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+                       BIT(IIO_CHAN_INFO_SCALE) |
+                       BIT(IIO_CHAN_INFO_INT_TIME)
+       }
+};
+
+static int tsl4531_read_raw(struct iio_dev *indio_dev,
+                               struct iio_chan_spec const *chan,
+                               int *val, int *val2, long mask)
+{
+       struct tsl4531_data *data = iio_priv(indio_dev);
+       int ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+               ret = i2c_smbus_read_word_data(data->client,
+                       TSL4531_DATA);
+               if (ret < 0)
+                       return ret;
+               *val = ret;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               /* 0.. 1x, 1 .. 2x, 2 .. 4x */
+               *val = 1 << data->int_time;
+               return IIO_VAL_INT;
+       case IIO_CHAN_INFO_INT_TIME:
+               if (data->int_time == 0)
+                       *val2 = 400000;
+               else if (data->int_time == 1)
+                       *val2 = 200000;
+               else if (data->int_time == 2)
+                       *val2 = 100000;
+               else
+                       return -EINVAL;
+               *val = 0;
+               return IIO_VAL_INT_PLUS_MICRO;
+       default:
+               return -EINVAL;
+       }
+}
+
+static int tsl4531_write_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            int val, int val2, long mask)
+{
+       struct tsl4531_data *data = iio_priv(indio_dev);
+       int int_time, ret;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_INT_TIME:
+               if (val != 0)
+                       return -EINVAL;
+               if (val2 == 400000)
+                       int_time = 0;
+               else if (val2 == 200000)
+                       int_time = 1;
+               else if (val2 == 100000)
+                       int_time = 2;
+               else
+                       return -EINVAL;
+               mutex_lock(&data->lock);
+               ret = i2c_smbus_write_byte_data(data->client,
+                       TSL4531_CONFIG, int_time);
+               if (ret >= 0)
+                       data->int_time = int_time;
+               mutex_unlock(&data->lock);
+               return ret;
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct iio_info tsl4531_info = {
+       .read_raw = tsl4531_read_raw,
+       .write_raw = tsl4531_write_raw,
+       .attrs = &tsl4531_attribute_group,
+       .driver_module = THIS_MODULE,
+};
+
+static int tsl4531_check_id(struct i2c_client *client)
+{
+       int ret = i2c_smbus_read_byte_data(client, TSL4531_ID);
+       if (ret < 0)
+               return ret;
+
+       switch (ret >> TSL4531_ID_SHIFT) {
+       case TSL45311_ID:
+       case TSL45313_ID:
+       case TSL45315_ID:
+       case TSL45317_ID:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static int tsl4531_probe(struct i2c_client *client,
+                         const struct i2c_device_id *id)
+{
+       struct tsl4531_data *data;
+       struct iio_dev *indio_dev;
+       int ret;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (!indio_dev)
+               return -ENOMEM;
+
+       data = iio_priv(indio_dev);
+       i2c_set_clientdata(client, indio_dev);
+       data->client = client;
+       mutex_init(&data->lock);
+
+       if (!tsl4531_check_id(client)) {
+               dev_err(&client->dev, "no TSL4531 sensor\n");
+               return -ENODEV;
+       }
+
+       ret = i2c_smbus_write_byte_data(data->client, TSL4531_CONTROL,
+               TSL4531_MODE_NORMAL);
+       if (ret < 0)
+               return ret;
+
+       ret = i2c_smbus_write_byte_data(data->client, TSL4531_CONFIG,
+               TSL4531_TCNTRL_400MS);
+       if (ret < 0)
+               return ret;
+
+       indio_dev->dev.parent = &client->dev;
+       indio_dev->info = &tsl4531_info;
+       indio_dev->channels = tsl4531_channels;
+       indio_dev->num_channels = ARRAY_SIZE(tsl4531_channels);
+       indio_dev->name = TSL4531_DRV_NAME;
+       indio_dev->modes = INDIO_DIRECT_MODE;
+
+       return iio_device_register(indio_dev);
+}
+
+static int tsl4531_powerdown(struct i2c_client *client)
+{
+       return i2c_smbus_write_byte_data(client, TSL4531_CONTROL,
+               TSL4531_MODE_POWERDOWN);
+}
+
+static int tsl4531_remove(struct i2c_client *client)
+{
+       iio_device_unregister(i2c_get_clientdata(client));
+       tsl4531_powerdown(client);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tsl4531_suspend(struct device *dev)
+{
+       return tsl4531_powerdown(to_i2c_client(dev));
+}
+
+static int tsl4531_resume(struct device *dev)
+{
+       return i2c_smbus_write_byte_data(to_i2c_client(dev), TSL4531_CONTROL,
+               TSL4531_MODE_NORMAL);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(tsl4531_pm_ops, tsl4531_suspend, tsl4531_resume);
+
+static const struct i2c_device_id tsl4531_id[] = {
+       { "tsl4531", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tsl4531_id);
+
+static struct i2c_driver tsl4531_driver = {
+       .driver = {
+               .name   = TSL4531_DRV_NAME,
+               .pm     = &tsl4531_pm_ops,
+               .owner  = THIS_MODULE,
+       },
+       .probe  = tsl4531_probe,
+       .remove = tsl4531_remove,
+       .id_table = tsl4531_id,
+};
+
+module_i2c_driver(tsl4531_driver);
+
+MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
+MODULE_DESCRIPTION("TAOS TSL4531 ambient light sensors driver");
+MODULE_LICENSE("GPL");
index a98460b15e4b63fc791494c32b1594993a12b6d1..2634920562fb7263bad4ac9d8c6c75fe7a434b49 100644 (file)
@@ -183,10 +183,11 @@ static const struct iio_info magn_3d_info = {
 };
 
 /* Function to push data to buffer */
-static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
+static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
+       int len)
 {
        dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+       iio_push_to_buffers(indio_dev, data);
 }
 
 /* Callback handler to send event after all samples are received and captured */
@@ -201,7 +202,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device *hsdev,
                                magn_state->common_attributes.data_ready);
        if (magn_state->common_attributes.data_ready)
                hid_sensor_push_data(indio_dev,
-                               (u8 *)magn_state->magn_val,
+                               magn_state->magn_val,
                                sizeof(magn_state->magn_val));
 
        return 0;
index 708857bdb47d3d4ba69a0fc65d1512defe4881c9..bf427dc0d226c40de9adc92257ece78ab6b14de6 100644 (file)
 
 static int st_magn_buffer_preenable(struct iio_dev *indio_dev)
 {
-       int err;
-
-       err = st_sensors_set_enable(indio_dev, true);
-       if (err < 0)
-               goto st_magn_set_enable_error;
-
-       err = iio_sw_buffer_preenable(indio_dev);
-
-st_magn_set_enable_error:
-       return err;
+       return st_sensors_set_enable(indio_dev, true);
 }
 
 static int st_magn_buffer_postenable(struct iio_dev *indio_dev)
index cab3bc7494a2260214a85874310ac80deca87c0a..52bbcfa1e07795208b45633ced62de0015772b74 100644 (file)
@@ -348,8 +348,9 @@ static const struct iio_info magn_info = {
 int st_magn_common_probe(struct iio_dev *indio_dev,
                                        struct st_sensors_platform_data *pdata)
 {
-       int err;
        struct st_sensor_data *mdata = iio_priv(indio_dev);
+       int irq = mdata->get_irq_data_ready(indio_dev);
+       int err;
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &magn_info;
@@ -357,7 +358,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
        err = st_sensors_check_device_support(indio_dev,
                                ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
        if (err < 0)
-               goto st_magn_common_probe_error;
+               return err;
 
        mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS;
        mdata->multiread_bit = mdata->sensor->multi_read_bit;
@@ -370,12 +371,13 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
 
        err = st_sensors_init_sensor(indio_dev, pdata);
        if (err < 0)
-               goto st_magn_common_probe_error;
+               return err;
 
-       if (mdata->get_irq_data_ready(indio_dev) > 0) {
-               err = st_magn_allocate_ring(indio_dev);
-               if (err < 0)
-                       goto st_magn_common_probe_error;
+       err = st_magn_allocate_ring(indio_dev);
+       if (err < 0)
+               return err;
+
+       if (irq > 0) {
                err = st_sensors_allocate_trigger(indio_dev, NULL);
                if (err < 0)
                        goto st_magn_probe_trigger_error;
@@ -385,15 +387,14 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
        if (err)
                goto st_magn_device_register_error;
 
-       return err;
+       return 0;
 
 st_magn_device_register_error:
-       if (mdata->get_irq_data_ready(indio_dev) > 0)
+       if (irq > 0)
                st_sensors_deallocate_trigger(indio_dev);
 st_magn_probe_trigger_error:
-       if (mdata->get_irq_data_ready(indio_dev) > 0)
-               st_magn_deallocate_ring(indio_dev);
-st_magn_common_probe_error:
+       st_magn_deallocate_ring(indio_dev);
+
        return err;
 }
 EXPORT_SYMBOL(st_magn_common_probe);
@@ -403,10 +404,10 @@ void st_magn_common_remove(struct iio_dev *indio_dev)
        struct st_sensor_data *mdata = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (mdata->get_irq_data_ready(indio_dev) > 0) {
+       if (mdata->get_irq_data_ready(indio_dev) > 0)
                st_sensors_deallocate_trigger(indio_dev);
-               st_magn_deallocate_ring(indio_dev);
-       }
+
+       st_magn_deallocate_ring(indio_dev);
 }
 EXPORT_SYMBOL(st_magn_common_remove);
 
index b0b630688da665138a97e3afbf33c1f387dda323..049c21acf1f051bfea9067c45ad7eb543b6361b2 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/iio/common/st_sensors.h>
 
+#define LPS001WP_PRESS_DEV_NAME                "lps001wp"
 #define LPS331AP_PRESS_DEV_NAME                "lps331ap"
 
 /**
index f877ef8af5201dfbabd03bc06b79db061111a12f..b37b1c9ac93210dc755ac95830fc956e428333ce 100644 (file)
@@ -32,16 +32,7 @@ int st_press_trig_set_state(struct iio_trigger *trig, bool state)
 
 static int st_press_buffer_preenable(struct iio_dev *indio_dev)
 {
-       int err;
-
-       err = st_sensors_set_enable(indio_dev, true);
-       if (err < 0)
-               goto st_press_set_enable_error;
-
-       err = iio_sw_buffer_preenable(indio_dev);
-
-st_press_set_enable_error:
-       return err;
+       return st_sensors_set_enable(indio_dev, true);
 }
 
 static int st_press_buffer_postenable(struct iio_dev *indio_dev)
index ceebd3c27892b183f6f276b1dbdb4d7a6a5a9a74..58083f9d51c56691281891e4afbbe368d92697ab 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/iio/sysfs.h>
 #include <linux/iio/trigger.h>
 #include <linux/iio/buffer.h>
+#include <linux/regulator/consumer.h>
 #include <asm/unaligned.h>
 
 #include <linux/iio/common/st_sensors.h>
                                                 ST_PRESS_LSB_PER_CELSIUS)
 #define ST_PRESS_NUMBER_DATA_CHANNELS          1
 
-/* DEFAULT VALUE FOR SENSORS */
-#define ST_PRESS_DEFAULT_OUT_XL_ADDR           0x28
-#define ST_TEMP_DEFAULT_OUT_L_ADDR             0x2b
-
 /* FULLSCALE */
 #define ST_PRESS_FS_AVL_1260MB                 1260
 
-/* CUSTOM VALUES FOR SENSOR 1 */
-#define ST_PRESS_1_WAI_EXP                     0xbb
-#define ST_PRESS_1_ODR_ADDR                    0x20
-#define ST_PRESS_1_ODR_MASK                    0x70
-#define ST_PRESS_1_ODR_AVL_1HZ_VAL             0x01
-#define ST_PRESS_1_ODR_AVL_7HZ_VAL             0x05
-#define ST_PRESS_1_ODR_AVL_13HZ_VAL            0x06
-#define ST_PRESS_1_ODR_AVL_25HZ_VAL            0x07
-#define ST_PRESS_1_PW_ADDR                     0x20
-#define ST_PRESS_1_PW_MASK                     0x80
-#define ST_PRESS_1_FS_ADDR                     0x23
-#define ST_PRESS_1_FS_MASK                     0x30
-#define ST_PRESS_1_FS_AVL_1260_VAL             0x00
-#define ST_PRESS_1_FS_AVL_1260_GAIN            ST_PRESS_KPASCAL_NANO_SCALE
-#define ST_PRESS_1_FS_AVL_TEMP_GAIN            ST_PRESS_CELSIUS_NANO_SCALE
-#define ST_PRESS_1_BDU_ADDR                    0x20
-#define ST_PRESS_1_BDU_MASK                    0x04
-#define ST_PRESS_1_DRDY_IRQ_ADDR               0x22
-#define ST_PRESS_1_DRDY_IRQ_INT1_MASK          0x04
-#define ST_PRESS_1_DRDY_IRQ_INT2_MASK          0x20
-#define ST_PRESS_1_MULTIREAD_BIT               true
-#define ST_PRESS_1_TEMP_OFFSET                 42500
-
-static const struct iio_chan_spec st_press_channels[] = {
-       ST_SENSORS_LSM_CHANNELS(IIO_PRESSURE,
+/* CUSTOM VALUES FOR LPS331AP SENSOR */
+#define ST_PRESS_LPS331AP_WAI_EXP              0xbb
+#define ST_PRESS_LPS331AP_ODR_ADDR             0x20
+#define ST_PRESS_LPS331AP_ODR_MASK             0x70
+#define ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL      0x01
+#define ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL      0x05
+#define ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL     0x06
+#define ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL     0x07
+#define ST_PRESS_LPS331AP_PW_ADDR              0x20
+#define ST_PRESS_LPS331AP_PW_MASK              0x80
+#define ST_PRESS_LPS331AP_FS_ADDR              0x23
+#define ST_PRESS_LPS331AP_FS_MASK              0x30
+#define ST_PRESS_LPS331AP_FS_AVL_1260_VAL      0x00
+#define ST_PRESS_LPS331AP_FS_AVL_1260_GAIN     ST_PRESS_KPASCAL_NANO_SCALE
+#define ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN     ST_PRESS_CELSIUS_NANO_SCALE
+#define ST_PRESS_LPS331AP_BDU_ADDR             0x20
+#define ST_PRESS_LPS331AP_BDU_MASK             0x04
+#define ST_PRESS_LPS331AP_DRDY_IRQ_ADDR                0x22
+#define ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK   0x04
+#define ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK   0x20
+#define ST_PRESS_LPS331AP_MULTIREAD_BIT                true
+#define ST_PRESS_LPS331AP_TEMP_OFFSET          42500
+#define ST_PRESS_LPS331AP_OUT_XL_ADDR          0x28
+#define ST_TEMP_LPS331AP_OUT_L_ADDR            0x2b
+
+/* CUSTOM VALUES FOR LPS001WP SENSOR */
+#define ST_PRESS_LPS001WP_WAI_EXP              0xba
+#define ST_PRESS_LPS001WP_ODR_ADDR             0x20
+#define ST_PRESS_LPS001WP_ODR_MASK             0x30
+#define ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL      0x01
+#define ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL      0x02
+#define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL     0x03
+#define ST_PRESS_LPS001WP_PW_ADDR              0x20
+#define ST_PRESS_LPS001WP_PW_MASK              0x40
+#define ST_PRESS_LPS001WP_BDU_ADDR             0x20
+#define ST_PRESS_LPS001WP_BDU_MASK             0x04
+#define ST_PRESS_LPS001WP_MULTIREAD_BIT                true
+#define ST_PRESS_LPS001WP_OUT_L_ADDR           0x28
+#define ST_TEMP_LPS001WP_OUT_L_ADDR            0x2a
+
+static const struct iio_chan_spec st_press_lps331ap_channels[] = {
+       {
+               .type = IIO_PRESSURE,
+               .channel2 = IIO_NO_MOD,
+               .address = ST_PRESS_LPS331AP_OUT_XL_ADDR,
+               .scan_index = ST_SENSORS_SCAN_X,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 24,
+                       .storagebits = 24,
+                       .endianness = IIO_LE,
+               },
+               .info_mask_separate =
                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
-                       ST_SENSORS_SCAN_X, 0, IIO_NO_MOD, 'u', IIO_LE, 24, 24,
-                       ST_PRESS_DEFAULT_OUT_XL_ADDR),
-       ST_SENSORS_LSM_CHANNELS(IIO_TEMP,
-                       BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
-                                               BIT(IIO_CHAN_INFO_OFFSET),
-                       -1, 0, IIO_NO_MOD, 's', IIO_LE, 16, 16,
-                       ST_TEMP_DEFAULT_OUT_L_ADDR),
+               .modified = 0,
+       },
+       {
+               .type = IIO_TEMP,
+               .channel2 = IIO_NO_MOD,
+               .address = ST_TEMP_LPS331AP_OUT_L_ADDR,
+               .scan_index = -1,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 16,
+                       .storagebits = 16,
+                       .endianness = IIO_LE,
+               },
+               .info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) |
+                       BIT(IIO_CHAN_INFO_SCALE) |
+                       BIT(IIO_CHAN_INFO_OFFSET),
+               .modified = 0,
+       },
+       IIO_CHAN_SOFT_TIMESTAMP(1)
+};
+
+static const struct iio_chan_spec st_press_lps001wp_channels[] = {
+       {
+               .type = IIO_PRESSURE,
+               .channel2 = IIO_NO_MOD,
+               .address = ST_PRESS_LPS001WP_OUT_L_ADDR,
+               .scan_index = ST_SENSORS_SCAN_X,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 16,
+                       .storagebits = 16,
+                       .endianness = IIO_LE,
+               },
+               .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+               .modified = 0,
+       },
+       {
+               .type = IIO_TEMP,
+               .channel2 = IIO_NO_MOD,
+               .address = ST_TEMP_LPS001WP_OUT_L_ADDR,
+               .scan_index = -1,
+               .scan_type = {
+                       .sign = 'u',
+                       .realbits = 16,
+                       .storagebits = 16,
+                       .endianness = IIO_LE,
+               },
+               .info_mask_separate =
+                       BIT(IIO_CHAN_INFO_RAW) |
+                       BIT(IIO_CHAN_INFO_OFFSET),
+               .modified = 0,
+       },
        IIO_CHAN_SOFT_TIMESTAMP(1)
 };
 
 static const struct st_sensors st_press_sensors[] = {
        {
-               .wai = ST_PRESS_1_WAI_EXP,
+               .wai = ST_PRESS_LPS331AP_WAI_EXP,
                .sensors_supported = {
                        [0] = LPS331AP_PRESS_DEV_NAME,
                },
-               .ch = (struct iio_chan_spec *)st_press_channels,
+               .ch = (struct iio_chan_spec *)st_press_lps331ap_channels,
+               .num_ch = ARRAY_SIZE(st_press_lps331ap_channels),
                .odr = {
-                       .addr = ST_PRESS_1_ODR_ADDR,
-                       .mask = ST_PRESS_1_ODR_MASK,
+                       .addr = ST_PRESS_LPS331AP_ODR_ADDR,
+                       .mask = ST_PRESS_LPS331AP_ODR_MASK,
                        .odr_avl = {
-                               { 1, ST_PRESS_1_ODR_AVL_1HZ_VAL, },
-                               { 7, ST_PRESS_1_ODR_AVL_7HZ_VAL, },
-                               { 13, ST_PRESS_1_ODR_AVL_13HZ_VAL, },
-                               { 25, ST_PRESS_1_ODR_AVL_25HZ_VAL, },
+                               { 1, ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL, },
+                               { 7, ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL, },
+                               { 13, ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL, },
+                               { 25, ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL, },
                        },
                },
                .pw = {
-                       .addr = ST_PRESS_1_PW_ADDR,
-                       .mask = ST_PRESS_1_PW_MASK,
+                       .addr = ST_PRESS_LPS331AP_PW_ADDR,
+                       .mask = ST_PRESS_LPS331AP_PW_MASK,
                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
                },
                .fs = {
-                       .addr = ST_PRESS_1_FS_ADDR,
-                       .mask = ST_PRESS_1_FS_MASK,
+                       .addr = ST_PRESS_LPS331AP_FS_ADDR,
+                       .mask = ST_PRESS_LPS331AP_FS_MASK,
                        .fs_avl = {
                                [0] = {
                                        .num = ST_PRESS_FS_AVL_1260MB,
-                                       .value = ST_PRESS_1_FS_AVL_1260_VAL,
-                                       .gain = ST_PRESS_1_FS_AVL_1260_GAIN,
-                                       .gain2 = ST_PRESS_1_FS_AVL_TEMP_GAIN,
+                                       .value = ST_PRESS_LPS331AP_FS_AVL_1260_VAL,
+                                       .gain = ST_PRESS_LPS331AP_FS_AVL_1260_GAIN,
+                                       .gain2 = ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN,
                                },
                        },
                },
                .bdu = {
-                       .addr = ST_PRESS_1_BDU_ADDR,
-                       .mask = ST_PRESS_1_BDU_MASK,
+                       .addr = ST_PRESS_LPS331AP_BDU_ADDR,
+                       .mask = ST_PRESS_LPS331AP_BDU_MASK,
                },
                .drdy_irq = {
-                       .addr = ST_PRESS_1_DRDY_IRQ_ADDR,
-                       .mask_int1 = ST_PRESS_1_DRDY_IRQ_INT1_MASK,
-                       .mask_int2 = ST_PRESS_1_DRDY_IRQ_INT2_MASK,
+                       .addr = ST_PRESS_LPS331AP_DRDY_IRQ_ADDR,
+                       .mask_int1 = ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK,
+                       .mask_int2 = ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK,
                },
-               .multi_read_bit = ST_PRESS_1_MULTIREAD_BIT,
+               .multi_read_bit = ST_PRESS_LPS331AP_MULTIREAD_BIT,
+               .bootime = 2,
+       },
+       {
+               .wai = ST_PRESS_LPS001WP_WAI_EXP,
+               .sensors_supported = {
+                       [0] = LPS001WP_PRESS_DEV_NAME,
+               },
+               .ch = (struct iio_chan_spec *)st_press_lps001wp_channels,
+               .num_ch = ARRAY_SIZE(st_press_lps001wp_channels),
+               .odr = {
+                       .addr = ST_PRESS_LPS001WP_ODR_ADDR,
+                       .mask = ST_PRESS_LPS001WP_ODR_MASK,
+                       .odr_avl = {
+                               { 1, ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL, },
+                               { 7, ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL, },
+                               { 13, ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL, },
+                       },
+               },
+               .pw = {
+                       .addr = ST_PRESS_LPS001WP_PW_ADDR,
+                       .mask = ST_PRESS_LPS001WP_PW_MASK,
+                       .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
+                       .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+               },
+               .fs = {
+                       .addr = 0,
+               },
+               .bdu = {
+                       .addr = ST_PRESS_LPS001WP_BDU_ADDR,
+                       .mask = ST_PRESS_LPS001WP_BDU_MASK,
+               },
+               .drdy_irq = {
+                       .addr = 0,
+               },
+               .multi_read_bit = ST_PRESS_LPS001WP_MULTIREAD_BIT,
                .bootime = 2,
        },
 };
@@ -207,44 +314,85 @@ static const struct iio_trigger_ops st_press_trigger_ops = {
 #define ST_PRESS_TRIGGER_OPS NULL
 #endif
 
+static void st_press_power_enable(struct iio_dev *indio_dev)
+{
+       struct st_sensor_data *pdata = iio_priv(indio_dev);
+       int err;
+
+       /* Regulators not mandatory, but if requested we should enable them. */
+       pdata->vdd = devm_regulator_get_optional(&indio_dev->dev, "vdd");
+       if (!IS_ERR(pdata->vdd)) {
+               err = regulator_enable(pdata->vdd);
+               if (err != 0)
+                       dev_warn(&indio_dev->dev,
+                                "Failed to enable specified Vdd supply\n");
+       }
+
+       pdata->vdd_io = devm_regulator_get_optional(&indio_dev->dev, "vddio");
+       if (!IS_ERR(pdata->vdd_io)) {
+               err = regulator_enable(pdata->vdd_io);
+               if (err != 0)
+                       dev_warn(&indio_dev->dev,
+                                "Failed to enable specified Vdd_IO supply\n");
+       }
+}
+
+static void st_press_power_disable(struct iio_dev *indio_dev)
+{
+       struct st_sensor_data *pdata = iio_priv(indio_dev);
+
+       if (!IS_ERR(pdata->vdd))
+               regulator_disable(pdata->vdd);
+
+       if (!IS_ERR(pdata->vdd_io))
+               regulator_disable(pdata->vdd_io);
+}
+
 int st_press_common_probe(struct iio_dev *indio_dev,
                                struct st_sensors_platform_data *plat_data)
 {
-       int err;
        struct st_sensor_data *pdata = iio_priv(indio_dev);
+       int irq = pdata->get_irq_data_ready(indio_dev);
+       int err;
 
        indio_dev->modes = INDIO_DIRECT_MODE;
        indio_dev->info = &press_info;
 
+       st_press_power_enable(indio_dev);
+
        err = st_sensors_check_device_support(indio_dev,
-                               ARRAY_SIZE(st_press_sensors), st_press_sensors);
+                                             ARRAY_SIZE(st_press_sensors),
+                                             st_press_sensors);
        if (err < 0)
-               goto st_press_common_probe_error;
+               return err;
 
        pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS;
-       pdata->multiread_bit = pdata->sensor->multi_read_bit;
-       indio_dev->channels = pdata->sensor->ch;
-       indio_dev->num_channels = ARRAY_SIZE(st_press_channels);
+       pdata->multiread_bit     = pdata->sensor->multi_read_bit;
+       indio_dev->channels      = pdata->sensor->ch;
+       indio_dev->num_channels  = pdata->sensor->num_ch;
+
+       if (pdata->sensor->fs.addr != 0)
+               pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
+                       &pdata->sensor->fs.fs_avl[0];
 
-       pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
-                                               &pdata->sensor->fs.fs_avl[0];
        pdata->odr = pdata->sensor->odr.odr_avl[0].hz;
 
-       if (!plat_data)
+       /* Some devices don't support a data ready pin. */
+       if (!plat_data && pdata->sensor->drdy_irq.addr)
                plat_data =
                        (struct st_sensors_platform_data *)&default_press_pdata;
 
        err = st_sensors_init_sensor(indio_dev, plat_data);
        if (err < 0)
-               goto st_press_common_probe_error;
+               return err;
 
-       if (pdata->get_irq_data_ready(indio_dev) > 0) {
-               err = st_press_allocate_ring(indio_dev);
-               if (err < 0)
-                       goto st_press_common_probe_error;
+       err = st_press_allocate_ring(indio_dev);
+       if (err < 0)
+               return err;
 
+       if (irq > 0) {
                err = st_sensors_allocate_trigger(indio_dev,
-                                                       ST_PRESS_TRIGGER_OPS);
+                                                 ST_PRESS_TRIGGER_OPS);
                if (err < 0)
                        goto st_press_probe_trigger_error;
        }
@@ -256,12 +404,11 @@ int st_press_common_probe(struct iio_dev *indio_dev,
        return err;
 
 st_press_device_register_error:
-       if (pdata->get_irq_data_ready(indio_dev) > 0)
+       if (irq > 0)
                st_sensors_deallocate_trigger(indio_dev);
 st_press_probe_trigger_error:
-       if (pdata->get_irq_data_ready(indio_dev) > 0)
-               st_press_deallocate_ring(indio_dev);
-st_press_common_probe_error:
+       st_press_deallocate_ring(indio_dev);
+
        return err;
 }
 EXPORT_SYMBOL(st_press_common_probe);
@@ -270,11 +417,13 @@ void st_press_common_remove(struct iio_dev *indio_dev)
 {
        struct st_sensor_data *pdata = iio_priv(indio_dev);
 
+       st_press_power_disable(indio_dev);
+
        iio_device_unregister(indio_dev);
-       if (pdata->get_irq_data_ready(indio_dev) > 0) {
+       if (pdata->get_irq_data_ready(indio_dev) > 0)
                st_sensors_deallocate_trigger(indio_dev);
-               st_press_deallocate_ring(indio_dev);
-       }
+
+       st_press_deallocate_ring(indio_dev);
 }
 EXPORT_SYMBOL(st_press_common_remove);
 
index 08aac5e6251dd11c770c240a81c38fd82773bc03..51eab7fcb1949894913048980895966792a5c4c9 100644 (file)
@@ -49,6 +49,7 @@ static int st_press_i2c_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id st_press_id_table[] = {
+       { LPS001WP_PRESS_DEV_NAME },
        { LPS331AP_PRESS_DEV_NAME },
        {},
 };
index 6d63883da1ab0e56be798538e1d965b1032eacb7..84a0789c3d96882de6db6c161e62c2feee444bc0 100644 (file)
@@ -70,12 +70,16 @@ static int tmp006_read_measurement(struct tmp006_data *data, u8 reg)
        return i2c_smbus_read_word_swapped(data->client, reg);
 }
 
+static const int tmp006_freqs[5][2] = { {4, 0}, {2, 0}, {1, 0},
+                                       {0, 500000}, {0, 250000} };
+
 static int tmp006_read_raw(struct iio_dev *indio_dev,
                            struct iio_chan_spec const *channel, int *val,
                            int *val2, long mask)
 {
        struct tmp006_data *data = iio_priv(indio_dev);
        s32 ret;
+       int cr;
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
@@ -106,6 +110,12 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,
                        break;
                }
                return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               cr = (data->config & TMP006_CONFIG_CR_MASK)
+                       >> TMP006_CONFIG_CR_SHIFT;
+               *val = tmp006_freqs[cr][0];
+               *val2 = tmp006_freqs[cr][1];
+               return IIO_VAL_INT_PLUS_MICRO;
        default:
                break;
        }
@@ -113,48 +123,32 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,
        return -EINVAL;
 }
 
-static const char * const tmp006_freqs[] = { "4", "2", "1", "0.5", "0.25" };
-
-static ssize_t tmp006_show_freq(struct device *dev,
-                               struct device_attribute *attr, char *buf)
-{
-       struct tmp006_data *data = iio_priv(dev_to_iio_dev(dev));
-       int cr = (data->config & TMP006_CONFIG_CR_MASK)
-               >> TMP006_CONFIG_CR_SHIFT;
-       return sprintf(buf, "%s\n", tmp006_freqs[cr]);
-}
-
-static ssize_t tmp006_store_freq(struct device *dev,
-                                struct device_attribute *attr,
-                                const char *buf, size_t len)
+static int tmp006_write_raw(struct iio_dev *indio_dev,
+                           struct iio_chan_spec const *chan,
+                           int val,
+                           int val2,
+                           long mask)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tmp006_data *data = iio_priv(indio_dev);
        int i;
-       bool found = false;
 
        for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++)
-               if (sysfs_streq(buf, tmp006_freqs[i])) {
-                       found = true;
-                       break;
-               }
-       if (!found)
-               return -EINVAL;
+               if ((val == tmp006_freqs[i][0]) &&
+                   (val2 == tmp006_freqs[i][1])) {
+                       data->config &= ~TMP006_CONFIG_CR_MASK;
+                       data->config |= i << TMP006_CONFIG_CR_SHIFT;
 
-       data->config &= ~TMP006_CONFIG_CR_MASK;
-       data->config |= i << TMP006_CONFIG_CR_SHIFT;
+                       return i2c_smbus_write_word_swapped(data->client,
+                                                           TMP006_CONFIG,
+                                                           data->config);
 
-       return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG,
-               data->config);
+               }
+       return -EINVAL;
 }
 
-static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR,
-                       tmp006_show_freq, tmp006_store_freq);
-
 static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");
 
 static struct attribute *tmp006_attributes[] = {
-       &iio_dev_attr_sampling_frequency.dev_attr.attr,
        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
        NULL
 };
@@ -168,16 +162,19 @@ static const struct iio_chan_spec tmp006_channels[] = {
                .type = IIO_VOLTAGE,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                        BIT(IIO_CHAN_INFO_SCALE),
+               .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
        },
        {
                .type = IIO_TEMP,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                        BIT(IIO_CHAN_INFO_SCALE),
+               .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
        }
 };
 
 static const struct iio_info tmp006_info = {
        .read_raw = tmp006_read_raw,
+       .write_raw = tmp006_write_raw,
        .attrs = &tmp006_attribute_group,
        .driver_module = THIS_MODULE,
 };
index effcd0ac98d84021c3ba439555342d660a025ef0..15e3b850f513e9158318bf5ff3ae420cf8a14500 100644 (file)
@@ -23,7 +23,7 @@ struct iio_sysfs_trig {
 };
 
 static LIST_HEAD(iio_sysfs_trig_list);
-static DEFINE_MUTEX(iio_syfs_trig_list_mut);
+static DEFINE_MUTEX(iio_sysfs_trig_list_mut);
 
 static int iio_sysfs_trigger_probe(int id);
 static ssize_t iio_sysfs_trig_add(struct device *dev,
@@ -135,7 +135,7 @@ static int iio_sysfs_trigger_probe(int id)
        struct iio_sysfs_trig *t;
        int ret;
        bool foundit = false;
-       mutex_lock(&iio_syfs_trig_list_mut);
+       mutex_lock(&iio_sysfs_trig_list_mut);
        list_for_each_entry(t, &iio_sysfs_trig_list, l)
                if (id == t->id) {
                        foundit = true;
@@ -169,7 +169,7 @@ static int iio_sysfs_trigger_probe(int id)
                goto out2;
        list_add(&t->l, &iio_sysfs_trig_list);
        __module_get(THIS_MODULE);
-       mutex_unlock(&iio_syfs_trig_list_mut);
+       mutex_unlock(&iio_sysfs_trig_list_mut);
        return 0;
 
 out2:
@@ -177,7 +177,7 @@ out2:
 free_t:
        kfree(t);
 out1:
-       mutex_unlock(&iio_syfs_trig_list_mut);
+       mutex_unlock(&iio_sysfs_trig_list_mut);
        return ret;
 }
 
@@ -185,14 +185,14 @@ static int iio_sysfs_trigger_remove(int id)
 {
        bool foundit = false;
        struct iio_sysfs_trig *t;
-       mutex_lock(&iio_syfs_trig_list_mut);
+       mutex_lock(&iio_sysfs_trig_list_mut);
        list_for_each_entry(t, &iio_sysfs_trig_list, l)
                if (id == t->id) {
                        foundit = true;
                        break;
                }
        if (!foundit) {
-               mutex_unlock(&iio_syfs_trig_list_mut);
+               mutex_unlock(&iio_sysfs_trig_list_mut);
                return -EINVAL;
        }
 
@@ -202,7 +202,7 @@ static int iio_sysfs_trigger_remove(int id)
        list_del(&t->l);
        kfree(t);
        module_put(THIS_MODULE);
-       mutex_unlock(&iio_syfs_trig_list_mut);
+       mutex_unlock(&iio_sysfs_trig_list_mut);
        return 0;
 }
 
index df9b24f7e2cb44efdb18e6b57fe4fa68562858b9..14b7390753ee7ce315780d92631a591158638870 100644 (file)
@@ -52,6 +52,7 @@ struct titsc {
        u32                     config_inp[4];
        u32                     bit_xp, bit_xn, bit_yp, bit_yn;
        u32                     inp_xp, inp_xn, inp_yp, inp_yn;
+       u32                     step_mask;
 };
 
 static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
@@ -196,7 +197,8 @@ static void titsc_step_config(struct titsc *ts_dev)
 
        /* The steps1 â€¦ end and bit 0 for TS_Charge */
        stepenable = (1 << (end_step + 2)) - 1;
-       am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable);
+       ts_dev->step_mask = stepenable;
+       am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask);
 }
 
 static void titsc_read_coordinates(struct titsc *ts_dev,
@@ -260,6 +262,10 @@ static irqreturn_t titsc_irq(int irq, void *dev)
        unsigned int fsm;
 
        status = titsc_readl(ts_dev, REG_IRQSTATUS);
+       /*
+        * ADC and touchscreen share the IRQ line.
+        * FIFO1 interrupts are used by ADC. Handle FIFO0 IRQs here only
+        */
        if (status & IRQENB_FIFO0THRES) {
 
                titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
@@ -316,7 +322,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
 
        if (irqclr) {
                titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
-               am335x_tsc_se_update(ts_dev->mfd_tscadc);
+               am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask);
                return IRQ_HANDLED;
        }
        return IRQ_NONE;
@@ -389,7 +395,7 @@ static int titsc_probe(struct platform_device *pdev)
        }
 
        err = request_irq(ts_dev->irq, titsc_irq,
-                         0, pdev->dev.driver->name, ts_dev);
+                         IRQF_SHARED, pdev->dev.driver->name, ts_dev);
        if (err) {
                dev_err(&pdev->dev, "failed to allocate irq.\n");
                goto err_free_mem;
index 4e2a81854f517cac05b775dd57d234e5d871e15e..45560ffb038d21e5ca5e7cf98afad3fdde634b29 100644 (file)
@@ -275,6 +275,12 @@ static int hid_time_probe(struct platform_device *pdev)
                return ret;
        }
 
+       ret = sensor_hub_device_open(hsdev);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to open sensor hub device!\n");
+               goto err_open;
+       }
+
        time_state->rtc = devm_rtc_device_register(&pdev->dev,
                                        "hid-sensor-time", &hid_time_rtc_ops,
                                        THIS_MODULE);
@@ -282,17 +288,24 @@ static int hid_time_probe(struct platform_device *pdev)
        if (IS_ERR_OR_NULL(time_state->rtc)) {
                ret = time_state->rtc ? PTR_ERR(time_state->rtc) : -ENODEV;
                time_state->rtc = NULL;
-               sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
                dev_err(&pdev->dev, "rtc device register failed!\n");
+               goto err_rtc;
        }
 
        return ret;
+
+err_rtc:
+       sensor_hub_device_close(hsdev);
+err_open:
+       sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
+       return ret;
 }
 
 static int hid_time_remove(struct platform_device *pdev)
 {
        struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
 
+       sensor_hub_device_close(hsdev);
        sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_TIME);
 
        return 0;
index 3626dbc8eb0bba5134f89aa19178fedb3e504e98..3b1501b7d894d13c282eca68d99eec4373cfa9a8 100644 (file)
@@ -136,6 +136,8 @@ source "drivers/staging/goldfish/Kconfig"
 
 source "drivers/staging/netlogic/Kconfig"
 
+source "drivers/staging/mt29f_spinand/Kconfig"
+
 source "drivers/staging/dwc2/Kconfig"
 
 source "drivers/staging/lustre/Kconfig"
@@ -148,4 +150,6 @@ source "drivers/staging/dgnc/Kconfig"
 
 source "drivers/staging/dgap/Kconfig"
 
+source "drivers/staging/ktap/Kconfig"
+
 endif # STAGING
index d1b4b8003c2d4de3898796e74d973cb2aa25f888..2270ed077bdef40e25cff88771b823ea6c6517d2 100644 (file)
@@ -66,3 +66,5 @@ obj-$(CONFIG_USB_BTMTK)               += btmtk_usb/
 obj-$(CONFIG_XILLYBUS)         += xillybus/
 obj-$(CONFIG_DGNC)                     += dgnc/
 obj-$(CONFIG_DGAP)                     += dgap/
+obj-$(CONFIG_MTD_SPINAND_MT29F)        += mt29f_spinand/
+obj-$(CONFIG_KTAP)             += ktap/
index c0c95be0f969de825119ce2a6ee535fd6668a63b..1e9ab6dfc90d446f84fdec75891a30683bb13927 100644 (file)
@@ -10,6 +10,7 @@ if ANDROID
 
 config ANDROID_BINDER_IPC
        bool "Android Binder IPC Driver"
+       depends on MMU
        default n
        ---help---
          Binder is used in Android for both communication between processes,
@@ -76,7 +77,7 @@ config SYNC
        bool "Synchronization framework"
        default n
        select ANON_INODES
-       help
+       ---help---
          This option enables the framework for synchronization between multiple
          drivers.  Sync implementations can take advantage of hardware
          synchronization built into devices like GPUs.
@@ -85,7 +86,7 @@ config SW_SYNC
        bool "Software synchronization objects"
        default n
        depends on SYNC
-       help
+       ---help---
          A sync object driver that uses a 32bit counter to coordinate
          syncrhronization.  Useful when there is no hardware primitive backing
          the synchronization.
@@ -94,7 +95,7 @@ config SW_SYNC_USER
        bool "Userspace API for SW_SYNC"
        default n
        depends on SW_SYNC
-       help
+       ---help---
          Provides a user space API to the sw sync object.
          *WARNING* improper use of this can result in deadlocking kernel
          drivers from userspace.
index 6dc27dac679d9133052b7aca2ad2ea06cf1d3486..647694f43dcf12fe9c30c300674f128569f79780 100644 (file)
@@ -60,7 +60,12 @@ struct devalarm {
 
 static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT];
 
-
+/**
+ * is_wakeup() - Checks to see if this alarm can wake the device
+ * @type:       The type of alarm being checked
+ *
+ * Return: 1 if this is a wakeup alarm, otherwise 0
+ */
 static int is_wakeup(enum android_alarm_type type)
 {
        return (type == ANDROID_ALARM_RTC_WAKEUP ||
@@ -76,7 +81,6 @@ static void devalarm_start(struct devalarm *alrm, ktime_t exp)
                hrtimer_start(&alrm->u.hrt, exp, HRTIMER_MODE_ABS);
 }
 
-
 static int devalarm_try_to_cancel(struct devalarm *alrm)
 {
        if (is_wakeup(alrm->type))
index 8e76ddca0999dd29e50d68f61d4f78c0ba6fbac3..db5325c88f1cb494a08d846e5f9a1d859fad00e4 100644 (file)
 #define ASHMEM_NAME_PREFIX_LEN (sizeof(ASHMEM_NAME_PREFIX) - 1)
 #define ASHMEM_FULL_NAME_LEN (ASHMEM_NAME_LEN + ASHMEM_NAME_PREFIX_LEN)
 
-/*
- * ashmem_area - anonymous shared memory area
- * Lifecycle: From our parent file's open() until its release()
- * Locking: Protected by `ashmem_mutex'
- * Big Note: Mappings do NOT pin this structure; it dies on close()
+/**
+ * struct ashmem_area - The anonymous shared memory area
+ * @name:              The optional name in /proc/pid/maps
+ * @unpinned_list:     The list of all ashmem areas
+ * @file:              The shmem-based backing file
+ * @size:              The size of the mapping, in bytes
+ * @prot_masks:                The allowed protection bits, as vm_flags
+ *
+ * The lifecycle of this structure is from our parent file's open() until
+ * its release(). It is also protected by 'ashmem_mutex'
+ *
+ * Warning: Mappings do NOT pin this structure; It dies on close()
  */
 struct ashmem_area {
-       char name[ASHMEM_FULL_NAME_LEN]; /* optional name in /proc/pid/maps */
-       struct list_head unpinned_list;  /* list of all ashmem areas */
-       struct file *file;               /* the shmem-based backing file */
-       size_t size;                     /* size of the mapping, in bytes */
-       unsigned long prot_mask;         /* allowed prot bits, as vm_flags */
+       char name[ASHMEM_FULL_NAME_LEN];
+       struct list_head unpinned_list;
+       struct file *file;
+       size_t size;
+       unsigned long prot_mask;
 };
 
-/*
- * ashmem_range - represents an interval of unpinned (evictable) pages
- * Lifecycle: From unpin to pin
- * Locking: Protected by `ashmem_mutex'
+/**
+ * struct ashmem_range - A range of unpinned/evictable pages
+ * @lru:                The entry in the LRU list
+ * @unpinned:           The entry in its area's unpinned list
+ * @asma:               The associated anonymous shared memory area.
+ * @pgstart:            The starting page (inclusive)
+ * @pgend:              The ending page (inclusive)
+ * @purged:             The purge status (ASHMEM_NOT or ASHMEM_WAS_PURGED)
+ *
+ * The lifecycle of this structure is from unpin to pin.
+ * It is protected by 'ashmem_mutex'
  */
 struct ashmem_range {
-       struct list_head lru;           /* entry in LRU list */
-       struct list_head unpinned;      /* entry in its area's unpinned list */
-       struct ashmem_area *asma;       /* associated area */
-       size_t pgstart;                 /* starting page, inclusive */
-       size_t pgend;                   /* ending page, inclusive */
-       unsigned int purged;            /* ASHMEM_NOT or ASHMEM_WAS_PURGED */
+       struct list_head lru;
+       struct list_head unpinned;
+       struct ashmem_area *asma;
+       size_t pgstart;
+       size_t pgend;
+       unsigned int purged;
 };
 
 /* LRU list of unpinned pages, protected by ashmem_mutex */
 static LIST_HEAD(ashmem_lru_list);
 
-/* Count of pages on our LRU list, protected by ashmem_mutex */
+/**
+ * long lru_count - The count of pages on our LRU list.
+ *
+ * This is protected by ashmem_mutex.
+ */
 static unsigned long lru_count;
 
-/*
+/**
  * ashmem_mutex - protects the list of and each individual ashmem_area
  *
  * Lock Ordering: ashmex_mutex -> i_mutex -> i_alloc_sem
@@ -105,28 +123,43 @@ static struct kmem_cache *ashmem_range_cachep __read_mostly;
 
 #define PROT_MASK              (PROT_EXEC | PROT_READ | PROT_WRITE)
 
+/**
+ * lru_add() - Adds a range of memory to the LRU list
+ * @range:     The memory range being added.
+ *
+ * The range is first added to the end (tail) of the LRU list.
+ * After this, the size of the range is added to @lru_count
+ */
 static inline void lru_add(struct ashmem_range *range)
 {
        list_add_tail(&range->lru, &ashmem_lru_list);
        lru_count += range_size(range);
 }
 
+/**
+ * lru_del() - Removes a range of memory from the LRU list
+ * @range:     The memory range being removed
+ *
+ * The range is first deleted from the LRU list.
+ * After this, the size of the range is removed from @lru_count
+ */
 static inline void lru_del(struct ashmem_range *range)
 {
        list_del(&range->lru);
        lru_count -= range_size(range);
 }
 
-/*
- * range_alloc - allocate and initialize a new ashmem_range structure
+/**
+ * range_alloc() - Allocates and initializes a new ashmem_range structure
+ * @asma:         The associated ashmem_area
+ * @prev_range:           The previous ashmem_range in the sorted asma->unpinned list
+ * @purged:       Initial purge status (ASMEM_NOT_PURGED or ASHMEM_WAS_PURGED)
+ * @start:        The starting page (inclusive)
+ * @end:          The ending page (inclusive)
  *
- * 'asma' - associated ashmem_area
- * 'prev_range' - the previous ashmem_range in the sorted asma->unpinned list
- * 'purged' - initial purge value (ASMEM_NOT_PURGED or ASHMEM_WAS_PURGED)
- * 'start' - starting page, inclusive
- * 'end' - ending page, inclusive
+ * This function is protected by ashmem_mutex.
  *
- * Caller must hold ashmem_mutex.
+ * Return: 0 if successful, or -ENOMEM if there is an error
  */
 static int range_alloc(struct ashmem_area *asma,
                       struct ashmem_range *prev_range, unsigned int purged,
@@ -151,6 +184,10 @@ static int range_alloc(struct ashmem_area *asma,
        return 0;
 }
 
+/**
+ * range_del() - Deletes and dealloctes an ashmem_range structure
+ * @range:      The associated ashmem_range that has previously been allocated
+ */
 static void range_del(struct ashmem_range *range)
 {
        list_del(&range->unpinned);
@@ -159,10 +196,17 @@ static void range_del(struct ashmem_range *range)
        kmem_cache_free(ashmem_range_cachep, range);
 }
 
-/*
- * range_shrink - shrinks a range
+/**
+ * range_shrink() - Shrinks an ashmem_range
+ * @range:         The associated ashmem_range being shrunk
+ * @start:         The starting byte of the new range
+ * @end:           The ending byte of the new range
  *
- * Caller must hold ashmem_mutex.
+ * This does not modify the data inside the existing range in any way - It
+ * simply shrinks the boundaries of the range.
+ *
+ * Theoretically, with a little tweaking, this could eventually be changed
+ * to range_resize, and expand the lru_count if the new range is larger.
  */
 static inline void range_shrink(struct ashmem_range *range,
                                size_t start, size_t end)
@@ -176,6 +220,16 @@ static inline void range_shrink(struct ashmem_range *range,
                lru_count -= pre - range_size(range);
 }
 
+/**
+ * ashmem_open() - Opens an Anonymous Shared Memory structure
+ * @inode:        The backing file's index node(?)
+ * @file:         The backing file
+ *
+ * Please note that the ashmem_area is not returned by this function - It is
+ * instead written to "file->private_data".
+ *
+ * Return: 0 if successful, or another code if unsuccessful.
+ */
 static int ashmem_open(struct inode *inode, struct file *file)
 {
        struct ashmem_area *asma;
@@ -197,6 +251,14 @@ static int ashmem_open(struct inode *inode, struct file *file)
        return 0;
 }
 
+/**
+ * ashmem_release() - Releases an Anonymous Shared Memory structure
+ * @ignored:         The backing file's Index Node(?) - It is ignored here.
+ * @file:            The backing file
+ *
+ * Return: 0 if successful. If it is anything else, go have a coffee and
+ * try again.
+ */
 static int ashmem_release(struct inode *ignored, struct file *file)
 {
        struct ashmem_area *asma = file->private_data;
@@ -214,6 +276,15 @@ static int ashmem_release(struct inode *ignored, struct file *file)
        return 0;
 }
 
+/**
+ * ashmem_read() - Reads a set of bytes from an Ashmem-enabled file
+ * @file:         The associated backing file.
+ * @buf:          The buffer of data being written to
+ * @len:          The number of bytes being read
+ * @pos:          The position of the first byte to read.
+ *
+ * Return: 0 if successful, or another return code if not.
+ */
 static ssize_t ashmem_read(struct file *file, char __user *buf,
                           size_t len, loff_t *pos)
 {
index 98ac020bf912fb8efd11872c3e992265734f510b..eaec1dab7fe489fbbc9d171a4acdf5f78d765df6 100644 (file)
@@ -1700,7 +1700,8 @@ err_no_context_mgr_node:
                thread->return_error = return_error;
 }
 
-int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
+static int binder_thread_write(struct binder_proc *proc,
+                       struct binder_thread *thread,
                        void __user *buffer, size_t size, size_t *consumed)
 {
        uint32_t cmd;
@@ -1773,7 +1774,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
                case BC_INCREFS_DONE:
                case BC_ACQUIRE_DONE: {
                        void __user *node_ptr;
-                       void *cookie;
+                       void __user *cookie;
                        struct binder_node *node;
 
                        if (get_user(node_ptr, (void * __user *)ptr))
@@ -2055,8 +2056,8 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
        return 0;
 }
 
-void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread,
-                   uint32_t cmd)
+static void binder_stat_br(struct binder_proc *proc,
+                          struct binder_thread *thread, uint32_t cmd)
 {
        trace_binder_return(cmd);
        if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) {
index ec907ab2ff5484fdfb87168b9f87ae9937582d3c..905c7cc9588e85998e6c918c09fb9f2a7884662d 100644 (file)
@@ -31,7 +31,7 @@ struct timed_output_dev {
        int             state;
 };
 
-extern int timed_output_dev_register(struct timed_output_dev *dev);
-extern void timed_output_dev_unregister(struct timed_output_dev *dev);
+int timed_output_dev_register(struct timed_output_dev *dev);
+void timed_output_dev_unregister(struct timed_output_dev *dev);
 
 #endif
index 4e470d4bb4e8f297c15ab40825f66e0ab7c9c239..a567894753aa831dab7e30f49568b4aaf006b192 100644 (file)
@@ -142,7 +142,8 @@ static void bcm_get_drvinfo(struct net_device *dev,
                            struct ethtool_drvinfo *info)
 {
        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev);
-       struct bcm_interface_adapter *psIntfAdapter = Adapter->pvInterfaceAdapter;
+       struct bcm_interface_adapter *psIntfAdapter =
+                                               Adapter->pvInterfaceAdapter;
        struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface);
 
        strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
index afca010f9db59b0ccc48820cedfabfa2163f2f31..d9fa2bb03e117c8d12e83ca649e8a701efa07441 100644 (file)
@@ -104,7 +104,7 @@ int BcmRDM(void *arg,
        void *buff,
        int len)
 {
-       return InterfaceRDM((struct bcm_interface_adapter*)arg, addr, buff, len);
+       return InterfaceRDM((struct bcm_interface_adapter *)arg, addr, buff, len);
 }
 
 int BcmWRM(void *arg,
index af5d22faa7f03c5a787d0cb054d8f5c50f2143a8..56c5bee6514e70cd63a69929966e1a931afc8b73 100644 (file)
@@ -596,7 +596,7 @@ ULONG PhsDeleteSFRules(IN void *pvContext, IN B_UINT16 uiVcid)
  * 0 if successful,
  * >0 Error.
  */
-ULONG PhsCompress(IN void *pvContext,
+static ULONG PhsCompress(IN void *pvContext,
                IN B_UINT16 uiVcid,
                IN B_UINT16 uiClsId,
                IN void *pvInputBuffer,
@@ -677,7 +677,7 @@ ULONG PhsCompress(IN void *pvContext,
  * 0 if successful,
  * >0 Error.
  */
-ULONG PhsDeCompress(IN void *pvContext,
+static ULONG PhsDeCompress(IN void *pvContext,
                IN B_UINT16 uiVcid,
                IN void *pvInputBuffer,
                OUT void *pvOutputBuffer,
@@ -829,7 +829,7 @@ UINT GetServiceFlowEntry(IN struct bcm_phs_table *psServiceFlowTable,
        return PHS_INVALID_TABLE_INDEX;
 }
 
-UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
+static UINT GetClassifierEntry(IN struct bcm_phs_classifier_table *pstClassifierTable,
                        IN B_UINT32 uiClsid, enum bcm_phs_classifier_context eClsContext,
                        OUT struct bcm_phs_classifier_entry **ppstClassifierEntry)
 {
@@ -880,7 +880,7 @@ static UINT GetPhsRuleEntry(IN struct bcm_phs_classifier_table *pstClassifierTab
        return PHS_INVALID_TABLE_INDEX;
 }
 
-UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16  uiClsId,
+static UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16  uiClsId,
                                IN struct bcm_phs_table *psServiceFlowTable,
                                struct bcm_phs_rule *psPhsRule,
                                B_UINT8 u8AssociatedPHSI)
@@ -913,7 +913,7 @@ UINT CreateSFToClassifierRuleMapping(IN B_UINT16 uiVcid, IN B_UINT16  uiClsId,
        return uiStatus;
 }
 
-UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
+static UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid,
                                IN B_UINT16 uiClsId,
                                IN struct bcm_phs_entry *pstServiceFlowEntry,
                                struct bcm_phs_rule *psPhsRule,
@@ -1239,7 +1239,7 @@ void DumpPhsRules(struct bcm_phs_extension *pDeviceExtension)
  *                     header.
  *     0       -If PHS rule is NULL.If PHSI is 0 indicateing packet as uncompressed.
  */
-int phs_decompress(unsigned char *in_buf,
+static int phs_decompress(unsigned char *in_buf,
                unsigned char *out_buf,
                struct bcm_phs_rule *decomp_phs_rules,
                UINT *header_size)
index 91a5715964b93727a61ad263bd6745ed5e54ad32..1f5b62b4b5a189dead3f85bbbe4406918df5301e 100644 (file)
@@ -103,7 +103,7 @@ static UCHAR ReadEEPROMStatusRegister(struct bcm_mini_adapter *Adapter)
                }
                if (!(dwRetries%RETRIES_PER_DELAY))
                        udelay(1000);
-               uiStatus = 0 ;
+               uiStatus = 0;
        }
        return uiData;
 } /* ReadEEPROMStatusRegister */
@@ -1095,7 +1095,7 @@ static int BeceemFlashBulkWrite(struct bcm_mini_adapter *Adapter,
                                goto BeceemFlashBulkWrite_EXIT;
                        }
                        uiTemp = uiTemp - 1;
-                       index = index + 1 ;
+                       index = index + 1;
                }
        }
        Adapter->SelectedChip = RESET_CHIP_SELECT;
@@ -1276,7 +1276,7 @@ static int BeceemFlashBulkWriteStatus(struct bcm_mini_adapter *Adapter,
                                goto BeceemFlashBulkWriteStatus_EXIT;
                        }
                        uiTemp = uiTemp - 1;
-                       index = index + 1 ;
+                       index = index + 1;
                }
        }
 
@@ -2831,7 +2831,7 @@ int BcmGetSectionValEndOffset(struct bcm_mini_adapter *Adapter, enum bcm_flash2x
                SectEndOffset = INVALID_OFFSET;
        }
 
-       return SectEndOffset ;
+       return SectEndOffset;
 }
 
 /*
@@ -3358,7 +3358,7 @@ int BcmSetActiveSection(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_secti
        /* struct bcm_dsd_header sDSD = {0};
         * struct bcm_iso_header sISO = {0};
         */
-       int HighestPriDSD = 0 ;
+       int HighestPriDSD = 0;
        int HighestPriISO = 0;
 
        Status = IsSectionWritable(Adapter, eFlash2xSectVal);
@@ -4450,7 +4450,7 @@ int WriteToFlashWithoutSectorErase(struct bcm_mini_adapter *Adapter,
                BcmDoChipSelect(Adapter, uiOffset);
                uiPartOffset = (uiOffset & (FLASH_PART_SIZE - 1)) + GetFlashBaseAddr(Adapter);
 
-               for (i = 0 ; i < uiNumBytes; i += Adapter->ulFlashWriteSize) {
+               for (i = 0; i < uiNumBytes; i += Adapter->ulFlashWriteSize) {
                        if (Adapter->ulFlashWriteSize == BYTE_WRITE_SUPPORT)
                                Status = flashByteWrite(Adapter, uiPartOffset, pcBuff);
                        else
index 0e783e8d71ca3e8691b1a1c00cfd54cd0d1c4691..7a9bf3b578104bf57939ce032c96dc17c88840be 100644 (file)
@@ -16,7 +16,8 @@
  *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *  or on the worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *  or on the worldwide web at
+ *  http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  *
  */
 
@@ -72,8 +73,9 @@ static int btmtk_usb_reset(struct usb_device *udev)
 
        BT_DBG("%s\n", __func__);
 
-       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, DEVICE_VENDOR_REQUEST_OUT,
-                                                 0x01, 0x00, NULL, 0x00, CONTROL_TIMEOUT_JIFFIES);
+       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
+                       DEVICE_VENDOR_REQUEST_OUT, 0x01, 0x00,
+                       NULL, 0x00, CONTROL_TIMEOUT_JIFFIES);
 
        if (ret < 0) {
                BT_ERR("%s error(%d)\n", __func__, ret);
@@ -91,20 +93,22 @@ static int btmtk_usb_io_read32(struct btmtk_usb_data *data, u32 reg, u32 *val)
        u8 request = data->r_request;
        struct usb_device *udev = data->udev;
        int ret;
+       __le32 val_le;
 
-       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), request, DEVICE_VENDOR_REQUEST_IN,
-                                                 0x0, reg, data->io_buf, 4,
-                                                 CONTROL_TIMEOUT_JIFFIES);
+       ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), request,
+                       DEVICE_VENDOR_REQUEST_IN, 0x0, reg, data->io_buf,
+                       4, CONTROL_TIMEOUT_JIFFIES);
 
        if (ret < 0) {
                *val = 0xffffffff;
-               BT_ERR("%s error(%d), reg=%x, value=%x\n", __func__, ret, reg, *val);
+               BT_ERR("%s error(%d), reg=%x, value=%x\n",
+                               __func__, ret, reg, *val);
                return ret;
        }
 
-       memmove(val, data->io_buf, 4);
+       memmove(&val_le, data->io_buf, 4);
 
-       *val = le32_to_cpu(*val);
+       *val = le32_to_cpu(val_le);
 
        if (ret > 0)
                ret = 0;
@@ -122,12 +126,13 @@ static int btmtk_usb_io_write32(struct btmtk_usb_data *data, u32 reg, u32 val)
        index = (u16)reg;
        value = val & 0x0000ffff;
 
-       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, DEVICE_VENDOR_REQUEST_OUT,
-                                                 value, index, NULL, 0,
-                                                 CONTROL_TIMEOUT_JIFFIES);
+       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request,
+                       DEVICE_VENDOR_REQUEST_OUT, value, index,
+                       NULL, 0, CONTROL_TIMEOUT_JIFFIES);
 
        if (ret < 0) {
-               BT_ERR("%s error(%d), reg=%x, value=%x\n", __func__, ret, reg, val);
+               BT_ERR("%s error(%d), reg=%x, value=%x\n",
+                               __func__, ret, reg, val);
                return ret;
        }
 
@@ -139,7 +144,8 @@ static int btmtk_usb_io_write32(struct btmtk_usb_data *data, u32 reg, u32 val)
                                value, index, NULL, 0, CONTROL_TIMEOUT_JIFFIES);
 
        if (ret < 0) {
-               BT_ERR("%s error(%d), reg=%x, value=%x\n", __func__, ret, reg, val);
+               BT_ERR("%s error(%d), reg=%x, value=%x\n",
+                               __func__, ret, reg, val);
                return ret;
        }
 
@@ -186,13 +192,15 @@ static void btmtk_usb_cap_init(struct btmtk_usb_data *data)
                ret = request_firmware(&firmware, MT7650_FIRMWARE, &udev->dev);
                if (ret < 0) {
                        if (ret == -ENOENT) {
-                               BT_ERR("Firmware file \"%s\" not found \n", MT7650_FIRMWARE);
+                               BT_ERR("Firmware file \"%s\" not found\n",
+                                               MT7650_FIRMWARE);
                        } else {
-                               BT_ERR("Firmware file \"%s\" request failed (err=%d) \n",
+                               BT_ERR("Firmware file \"%s\" request failed (err=%d)\n",
                                        MT7650_FIRMWARE, ret);
                        }
                } else {
-                       BT_DBG("Firmware file \"%s\" Found \n", MT7650_FIRMWARE);
+                       BT_DBG("Firmware file \"%s\" Found\n",
+                                       MT7650_FIRMWARE);
                        /* load firmware here */
                        data->firmware = firmware;
                        btmtk_usb_load_fw(data);
@@ -205,7 +213,8 @@ static void btmtk_usb_cap_init(struct btmtk_usb_data *data)
                ret = request_firmware(&firmware, MT7662_FIRMWARE, &udev->dev);
                if (ret < 0) {
                        if (ret == -ENOENT) {
-                               BT_ERR("Firmware file \"%s\" not found\n", MT7662_FIRMWARE);
+                               BT_ERR("Firmware file \"%s\" not found\n",
+                                               MT7662_FIRMWARE);
                        } else {
                                BT_ERR("Firmware file \"%s\" request failed (err=%d)\n",
                                        MT7662_FIRMWARE, ret);
@@ -241,9 +250,8 @@ static u16 checksume16(u8 *pData, int len)
        if (len)
                sum += *((u8 *)pData);
 
-       while (sum >> 16) {
+       while (sum >> 16)
                sum = (sum & 0xFFFF) + (sum >> 16);
-       }
 
        return ~sum;
 }
@@ -258,13 +266,12 @@ static int btmtk_usb_chk_crc(struct btmtk_usb_data *data, u32 checksum_len)
        memmove(data->io_buf, &data->rom_patch_offset, 4);
        memmove(&data->io_buf[4], &checksum_len, 4);
 
-       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x1, DEVICE_VENDOR_REQUEST_IN,
-                                                 0x20, 0x00, data->io_buf, 8,
-                                                 CONTROL_TIMEOUT_JIFFIES);
+       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x1,
+                       DEVICE_VENDOR_REQUEST_IN, 0x20, 0x00, data->io_buf,
+                       8, CONTROL_TIMEOUT_JIFFIES);
 
-       if (ret < 0) {
+       if (ret < 0)
                BT_ERR("%s error(%d)\n", __func__, ret);
-       }
 
        return ret;
 }
@@ -274,6 +281,7 @@ static u16 btmtk_usb_get_crc(struct btmtk_usb_data *data)
        int ret = 0;
        struct usb_device *udev = data->udev;
        u16 crc, count = 0;
+       __le16 crc_le;
 
        BT_DBG("%s\n", __func__);
 
@@ -288,9 +296,9 @@ static u16 btmtk_usb_get_crc(struct btmtk_usb_data *data)
                        BT_ERR("%s error(%d)\n", __func__, ret);
                }
 
-               memmove(&crc, data->io_buf, 2);
+               memmove(&crc_le, data->io_buf, 2);
 
-               crc = le16_to_cpu(crc);
+               crc = le16_to_cpu(crc_le);
 
                if (crc != 0xFFFF)
                        break;
@@ -318,8 +326,8 @@ static int btmtk_usb_reset_wmt(struct btmtk_usb_data *data)
        BT_DBG("%s\n", __func__);
 
        ret = usb_control_msg(data->udev, usb_sndctrlpipe(data->udev, 0), 0x01,
-                               DEVICE_CLASS_REQUEST_OUT, 0x12, 0x00, data->io_buf,
-                               8, CONTROL_TIMEOUT_JIFFIES);
+                               DEVICE_CLASS_REQUEST_OUT, 0x12, 0x00,
+                               data->io_buf, 8, CONTROL_TIMEOUT_JIFFIES);
 
        if (ret)
                BT_ERR("%s:(%d)\n", __func__, ret);
@@ -350,7 +358,8 @@ static int btmtk_usb_load_rom_patch(struct btmtk_usb_data *data)
        unsigned char phase;
        void *buf;
        char *pos;
-       unsigned int pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
+       unsigned int pipe;
+       pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
 
        if (!data->firmware) {
                BT_ERR("%s:please assign a rom patch\n", __func__);
@@ -391,7 +400,8 @@ load_patch_protect:
                goto error0;
        }
 
-       buf = usb_alloc_coherent(data->udev, UPLOAD_PATCH_UNIT, GFP_ATOMIC, &data_dma);
+       buf = usb_alloc_coherent(data->udev, UPLOAD_PATCH_UNIT,
+                       GFP_ATOMIC, &data_dma);
 
        if (!buf) {
                ret = -ENOMEM;
@@ -409,78 +419,82 @@ load_patch_protect:
        /* loading rom patch */
        while (1) {
                s32 sent_len_max = UPLOAD_PATCH_UNIT - PATCH_HEADER_SIZE;
-               sent_len = (patch_len - cur_len) >= sent_len_max ? sent_len_max : (patch_len - cur_len);
+               sent_len = min_t(s32, (patch_len - cur_len), sent_len_max);
 
                BT_DBG("patch_len = %d\n", patch_len);
                BT_DBG("cur_len = %d\n", cur_len);
                BT_DBG("sent_len = %d\n", sent_len);
 
-               if (sent_len > 0) {
-                       if (first_block == 1) {
-                               if (sent_len < sent_len_max)
-                                       phase = PATCH_PHASE3;
-                               else
-                                       phase = PATCH_PHASE1;
-                               first_block = 0;
-                       } else if (sent_len == sent_len_max) {
-                               phase = PATCH_PHASE2;
-                       } else {
+               if (sent_len <= 0)
+                       break;
+
+               if (first_block == 1) {
+                       if (sent_len < sent_len_max)
                                phase = PATCH_PHASE3;
-                       }
+                       else
+                               phase = PATCH_PHASE1;
+                       first_block = 0;
+               } else if (sent_len == sent_len_max) {
+                       phase = PATCH_PHASE2;
+               } else {
+                       phase = PATCH_PHASE3;
+               }
 
-                       /* prepare HCI header */
-                       pos[0] = 0x6F;
-                       pos[1] = 0xFC;
-                       pos[2] = (sent_len + 5) & 0xFF;
-                       pos[3] = ((sent_len + 5) >> 8) & 0xFF;
+               /* prepare HCI header */
+               pos[0] = 0x6F;
+               pos[1] = 0xFC;
+               pos[2] = (sent_len + 5) & 0xFF;
+               pos[3] = ((sent_len + 5) >> 8) & 0xFF;
 
-                       /* prepare WMT header */
-                       pos[4] = 0x01;
-                       pos[5] = 0x01;
-                       pos[6] = (sent_len + 1) & 0xFF;
-                       pos[7] = ((sent_len + 1) >> 8) & 0xFF;
+               /* prepare WMT header */
+               pos[4] = 0x01;
+               pos[5] = 0x01;
+               pos[6] = (sent_len + 1) & 0xFF;
+               pos[7] = ((sent_len + 1) >> 8) & 0xFF;
 
-                       pos[8] = phase;
+               pos[8] = phase;
 
-                       memcpy(&pos[9], data->firmware->data + PATCH_INFO_SIZE + cur_len, sent_len);
+               memcpy(&pos[9],
+                       data->firmware->data + PATCH_INFO_SIZE + cur_len,
+                       sent_len);
 
-                       BT_DBG("sent_len + PATCH_HEADER_SIZE = %d, phase = %d\n",
-                                       sent_len + PATCH_HEADER_SIZE, phase);
+               BT_DBG("sent_len + PATCH_HEADER_SIZE = %d, phase = %d\n",
+                               sent_len + PATCH_HEADER_SIZE, phase);
 
-                       usb_fill_bulk_urb(urb,
-                                       data->udev,
-                                       pipe,
-                                       buf,
-                                       sent_len + PATCH_HEADER_SIZE,
-                                       load_rom_patch_complete,
-                                       &sent_to_mcu_done);
+               usb_fill_bulk_urb(urb,
+                               data->udev,
+                               pipe,
+                               buf,
+                               sent_len + PATCH_HEADER_SIZE,
+                               load_rom_patch_complete,
+                               &sent_to_mcu_done);
 
-                       urb->transfer_dma = data_dma;
-                       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+               urb->transfer_dma = data_dma;
+               urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-                       ret = usb_submit_urb(urb, GFP_ATOMIC);
+               ret = usb_submit_urb(urb, GFP_ATOMIC);
 
-                       if (ret)
-                               goto error2;
+               if (ret)
+                       goto error2;
 
-                       if (!wait_for_completion_timeout(&sent_to_mcu_done, msecs_to_jiffies(1000))) {
-                               usb_kill_urb(urb);
-                               BT_ERR("upload rom_patch timeout\n");
-                               goto error2;
-                       }
+               if (!wait_for_completion_timeout(&sent_to_mcu_done,
+                                       msecs_to_jiffies(1000))) {
+                       usb_kill_urb(urb);
+                       BT_ERR("upload rom_patch timeout\n");
+                       goto error2;
+               }
 
-                       BT_DBG(".");
+               BT_DBG(".");
 
-                       mdelay(200);
+               mdelay(200);
 
-                       cur_len += sent_len;
+               cur_len += sent_len;
 
-               } else {
-                       break;
-               }
        }
 
-       total_checksum = checksume16((u8 *)data->firmware->data + PATCH_INFO_SIZE, patch_len);
+       total_checksum = checksume16(
+                       (u8 *)data->firmware->data + PATCH_INFO_SIZE,
+                       patch_len);
 
        BT_DBG("Send checksum req..\n");
 
@@ -520,8 +534,8 @@ static int load_fw_iv(struct btmtk_usb_data *data)
        memmove(buf, data->firmware->data + 32, 64);
 
        ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01,
-                                                 DEVICE_VENDOR_REQUEST_OUT, 0x12, 0x0, buf, 64,
-                                                 CONTROL_TIMEOUT_JIFFIES);
+                       DEVICE_VENDOR_REQUEST_OUT, 0x12, 0x0, buf, 64,
+                       CONTROL_TIMEOUT_JIFFIES);
 
        if (ret < 0) {
                BT_ERR("%s error(%d) step4\n", __func__, ret);
@@ -552,6 +566,7 @@ static int btmtk_usb_load_fw(struct btmtk_usb_data *data)
        void *buf;
        u32 cur_len = 0;
        u32 packet_header = 0;
+       __le32 packet_header_le;
        u32 value;
        u32 ilm_len = 0, dlm_len = 0;
        u16 fw_ver, build_ver;
@@ -559,7 +574,8 @@ static int btmtk_usb_load_fw(struct btmtk_usb_data *data)
        dma_addr_t data_dma;
        int ret = 0, sent_len;
        struct completion sent_to_mcu_done;
-       unsigned int pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
+       unsigned int pipe;
+       pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress);
 
        if (!data->firmware) {
                BT_ERR("%s:please assign a fw\n", __func__);
@@ -598,9 +614,11 @@ loadfw_protect:
                        | (*(data->firmware->data + 5) << 8)
                        | (*(data->firmware->data + 4));
 
-       fw_ver = (*(data->firmware->data + 11) << 8) | (*(data->firmware->data + 10));
+       fw_ver = (*(data->firmware->data + 11) << 8) |
+             (*(data->firmware->data + 10));
 
-       build_ver = (*(data->firmware->data + 9) << 8) | (*(data->firmware->data + 8));
+       build_ver = (*(data->firmware->data + 9) << 8) |
+                (*(data->firmware->data + 8));
 
        BT_DBG("fw version:%d.%d.%02d ",
                        (fw_ver & 0xf000) >> 8,
@@ -657,22 +675,22 @@ loadfw_protect:
 
        /* Loading ILM */
        while (1) {
-               sent_len = (ilm_len - cur_len) >= 14336 ? 14336 : (ilm_len - cur_len);
+               sent_len = min_t(s32, (ilm_len - cur_len), 14336);
 
                if (sent_len > 0) {
                        packet_header &= ~(0xffffffff);
                        packet_header |= (sent_len << 16);
-                       packet_header = cpu_to_le32(packet_header);
+                       packet_header_le = cpu_to_le32(packet_header);
 
-                       memmove(buf, &packet_header, 4);
-                       memmove(buf + 4, data->firmware->data + 32 + cur_len, sent_len);
+                       memmove(buf, &packet_header_le, 4);
+                       memmove(buf + 4, data->firmware->data + 32 + cur_len,
+                                       sent_len);
 
                        /* U2M_PDMA descriptor */
                        btmtk_usb_io_write32(data, 0x230, cur_len);
 
-                       while ((sent_len % 4) != 0) {
+                       while ((sent_len % 4) != 0)
                                sent_len++;
-                       }
 
                        /* U2M_PDMA length */
                        btmtk_usb_io_write32(data, 0x234, sent_len << 16);
@@ -693,7 +711,8 @@ loadfw_protect:
                        if (ret)
                                goto error3;
 
-                       if (!wait_for_completion_timeout(&sent_to_mcu_done, msecs_to_jiffies(1000))) {
+                       if (!wait_for_completion_timeout(&sent_to_mcu_done,
+                                               msecs_to_jiffies(1000))) {
                                usb_kill_urb(urb);
                                BT_ERR("upload ilm fw timeout\n");
                                goto error3;
@@ -714,58 +733,60 @@ loadfw_protect:
 
        /* Loading DLM */
        while (1) {
-               sent_len = (dlm_len - cur_len) >= 14336 ? 14336 : (dlm_len - cur_len);
+               sent_len = min_t(s32, (dlm_len - cur_len), 14336);
 
-               if (sent_len > 0) {
-                       packet_header &= ~(0xffffffff);
-                       packet_header |= (sent_len << 16);
-                       packet_header = cpu_to_le32(packet_header);
+               if (sent_len <= 0)
+                       break;
 
-                       memmove(buf, &packet_header, 4);
-                       memmove(buf + 4, data->firmware->data + 32 + ilm_len + cur_len, sent_len);
+               packet_header &= ~(0xffffffff);
+               packet_header |= (sent_len << 16);
+               packet_header_le = cpu_to_le32(packet_header);
 
-                       /* U2M_PDMA descriptor */
-                       btmtk_usb_io_write32(data, 0x230, 0x80000 + cur_len);
+               memmove(buf, &packet_header_le, 4);
+               memmove(buf + 4,
+                       data->firmware->data + 32 + ilm_len + cur_len,
+                       sent_len);
 
-                       while ((sent_len % 4) != 0) {
-                               BT_DBG("sent_len is not divided by 4\n");
-                               sent_len++;
-                       }
+               /* U2M_PDMA descriptor */
+               btmtk_usb_io_write32(data, 0x230, 0x80000 + cur_len);
 
-                       /* U2M_PDMA length */
-                       btmtk_usb_io_write32(data, 0x234, sent_len << 16);
+               while ((sent_len % 4) != 0) {
+                       BT_DBG("sent_len is not divided by 4\n");
+                       sent_len++;
+               }
 
-                       usb_fill_bulk_urb(urb,
-                                       udev,
-                                       pipe,
-                                       buf,
-                                       sent_len + 4,
-                                       load_fw_complete,
-                                       &sent_to_mcu_done);
+               /* U2M_PDMA length */
+               btmtk_usb_io_write32(data, 0x234, sent_len << 16);
 
-                       urb->transfer_dma = data_dma;
-                       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+               usb_fill_bulk_urb(urb,
+                               udev,
+                               pipe,
+                               buf,
+                               sent_len + 4,
+                               load_fw_complete,
+                               &sent_to_mcu_done);
 
-                       ret = usb_submit_urb(urb, GFP_ATOMIC);
+               urb->transfer_dma = data_dma;
+               urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-                       if (ret)
-                               goto error3;
+               ret = usb_submit_urb(urb, GFP_ATOMIC);
 
-                       if (!wait_for_completion_timeout(&sent_to_mcu_done, msecs_to_jiffies(1000))) {
-                               usb_kill_urb(urb);
-                               BT_ERR("upload dlm fw timeout\n");
-                               goto error3;
-                       }
+               if (ret)
+                       goto error3;
 
-                       BT_DBG(".");
+               if (!wait_for_completion_timeout(&sent_to_mcu_done,
+                                       msecs_to_jiffies(1000))) {
+                       usb_kill_urb(urb);
+                       BT_ERR("upload dlm fw timeout\n");
+                       goto error3;
+               }
 
-                       mdelay(500);
+               BT_DBG(".");
 
-                       cur_len += sent_len;
+               mdelay(500);
+
+               cur_len += sent_len;
 
-               } else {
-                       break;
-               }
        }
 
        /* upload 64bytes interrupt vector */
@@ -921,9 +942,8 @@ static void btmtk_usb_bulk_in_complete(struct urb *urb)
        BT_DBG("%s:%s urb %p status %d count %d", __func__, hdev->name,
                                        urb, urb->status, urb->actual_length);
 
-       if (!test_bit(HCI_RUNNING, &hdev->flags)) {
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
                return;
-       }
 
        if (urb->status == 0) {
                hdev->stat.byte_rx += urb->actual_length;
@@ -978,8 +998,8 @@ static int btmtk_usb_submit_bulk_in_urb(struct hci_dev *hdev, gfp_t mem_flags)
 
        pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
 
-       usb_fill_bulk_urb(urb, data->udev, pipe,
-                                       buf, size, btmtk_usb_bulk_in_complete, hdev);
+       usb_fill_bulk_urb(urb, data->udev, pipe, buf, size,
+                       btmtk_usb_bulk_in_complete, hdev);
 
        urb->transfer_flags |= URB_FREE_BUFFER;
 
@@ -1015,7 +1035,8 @@ static void btmtk_usb_isoc_in_complete(struct urb *urb)
        if (urb->status == 0) {
                for (i = 0; i < urb->number_of_packets; i++) {
                        unsigned int offset = urb->iso_frame_desc[i].offset;
-                       unsigned int length = urb->iso_frame_desc[i].actual_length;
+                       unsigned int length;
+                       length = urb->iso_frame_desc[i].actual_length;
 
                        if (urb->iso_frame_desc[i].status)
                                continue;
@@ -1096,8 +1117,9 @@ static int btmtk_usb_submit_isoc_in_urb(struct hci_dev *hdev, gfp_t mem_flags)
 
        pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
 
-       usb_fill_int_urb(urb, data->udev, pipe, buf, size, btmtk_usb_isoc_in_complete,
-                               hdev, data->isoc_rx_ep->bInterval);
+       usb_fill_int_urb(urb, data->udev, pipe, buf, size,
+                       btmtk_usb_isoc_in_complete, hdev,
+                       data->isoc_rx_ep->bInterval);
 
        urb->transfer_flags  = URB_FREE_BUFFER | URB_ISO_ASAP;
 
@@ -1306,7 +1328,8 @@ static int btmtk_usb_send_frame(struct sk_buff *skb)
                }
 
                usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
-                               skb->data, skb->len, btmtk_usb_tx_complete, skb);
+                               skb->data, skb->len,
+                               btmtk_usb_tx_complete, skb);
 
                hdev->stat.cmd_tx++;
                break;
@@ -1322,8 +1345,8 @@ static int btmtk_usb_send_frame(struct sk_buff *skb)
                pipe = usb_sndbulkpipe(data->udev,
                                        data->bulk_tx_ep->bEndpointAddress);
 
-               usb_fill_bulk_urb(urb, data->udev, pipe,
-                               skb->data, skb->len, btmtk_usb_tx_complete, skb);
+               usb_fill_bulk_urb(urb, data->udev, pipe, skb->data,
+                               skb->len, btmtk_usb_tx_complete, skb);
 
                hdev->stat.acl_tx++;
                BT_DBG("HCI_ACLDATA_PKT:\n");
@@ -1442,7 +1465,8 @@ static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
 
 static void btmtk_usb_work(struct work_struct *work)
 {
-       struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data, work);
+       struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data,
+                       work);
        struct hci_dev *hdev = data->hdev;
        int new_alts;
        int err;
@@ -1451,7 +1475,8 @@ static void btmtk_usb_work(struct work_struct *work)
 
        if (hdev->conn_hash.sco_num > 0) {
                if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
-                       err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
+                       err = usb_autopm_get_interface(data->isoc ?
+                                       data->isoc : data->intf);
                        if (err < 0) {
                                clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
                                usb_kill_anchored_urbs(&data->isoc_anchor);
@@ -1489,13 +1514,15 @@ static void btmtk_usb_work(struct work_struct *work)
                __set_isoc_interface(hdev, 0);
 
                if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
-                        usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
+                       usb_autopm_put_interface(data->isoc ?
+                                        data->isoc : data->intf);
        }
 }
 
 static void btmtk_usb_waker(struct work_struct *work)
 {
-       struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data, waker);
+       struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data,
+                       waker);
        int err;
 
        err = usb_autopm_get_interface(data->intf);
index 2dbaf39e2fc296b0b5acfc6b32fd0f9bb67d80e3..62efd74b8c04746da6cb1ccfa425139fa67e89bf 100644 (file)
@@ -692,10 +692,7 @@ static int SetArea(DEVICE_EXTENSION *pdx, int nArea, char __user *puBuf,
                __func__, puBuf, dwLength, bCircular);
 
        /*  To pin down user pages we must first acquire the mapping semaphore. */
-       down_read(&current->mm->mmap_sem);      /*  get memory map semaphore */
-       nPages = get_user_pages(current, current->mm, ulStart, len, 1, 0,
-                               pPages, NULL);
-       up_read(&current->mm->mmap_sem);        /*  release the semaphore */
+       nPages = get_user_pages_fast(ulStart, len, 1, pPages);
        dev_dbg(&pdx->interface->dev, "%s nPages = %d", __func__, nPages);
 
        if (nPages > 0) {               /*  if we succeeded */
index f73287eab373a92b7f1a9876c3e53eb7f2cee327..bfa27e7fc0169feb81a0dc631c7a85f565dea107 100644 (file)
@@ -485,6 +485,7 @@ config COMEDI_NI_ATMIO
        tristate "NI AT-MIO E series ISA-PNP card support"
        select COMEDI_8255
        select COMEDI_NI_TIO
+       select COMEDI_FC
        ---help---
          Enable support for National Instruments AT-MIO E series cards
          National Instruments AT-MIO-16E-1 (ni_atmio),
@@ -990,8 +991,6 @@ config COMEDI_ME_DAQ
 
 config COMEDI_NI_6527
        tristate "NI 6527 support"
-       depends on HAS_DMA
-       select COMEDI_MITE
        ---help---
          Enable support for the National Instruments 6527 PCI card
 
index 94b2385fb0af29afc1812f0029ee28d47ff64608..4e26bd7fc84f3560135296aea5cadd736df7797d 100644 (file)
@@ -344,7 +344,7 @@ unsigned int comedi_buf_read_free(struct comedi_async *async,
 }
 EXPORT_SYMBOL_GPL(comedi_buf_read_free);
 
-int comedi_buf_put(struct comedi_async *async, short x)
+int comedi_buf_put(struct comedi_async *async, unsigned short x)
 {
        unsigned int n = __comedi_buf_write_alloc(async, sizeof(short), 1);
 
@@ -352,20 +352,20 @@ int comedi_buf_put(struct comedi_async *async, short x)
                async->events |= COMEDI_CB_ERROR;
                return 0;
        }
-       *(short *)(async->prealloc_buf + async->buf_write_ptr) = x;
+       *(unsigned short *)(async->prealloc_buf + async->buf_write_ptr) = x;
        comedi_buf_write_free(async, sizeof(short));
        return 1;
 }
 EXPORT_SYMBOL_GPL(comedi_buf_put);
 
-int comedi_buf_get(struct comedi_async *async, short *x)
+int comedi_buf_get(struct comedi_async *async, unsigned short *x)
 {
        unsigned int n = comedi_buf_read_n_available(async);
 
        if (n < sizeof(short))
                return 0;
        comedi_buf_read_alloc(async, sizeof(short));
-       *x = *(short *)(async->prealloc_buf + async->buf_read_ptr);
+       *x = *(unsigned short *)(async->prealloc_buf + async->buf_read_ptr);
        comedi_buf_read_free(async, sizeof(short));
        return 1;
 }
index 1636c7ca57e237fcd516141933c5047ee12131da..721df313f8df2f5b598da82be43991da93dadcda 100644 (file)
@@ -543,7 +543,7 @@ void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size)
 {
        s->private = kzalloc(size, GFP_KERNEL);
        if (s->private)
-               comedi_set_subdevice_runflags(s, ~0, SRF_FREE_SPRIV);
+               s->runflags |= SRF_FREE_SPRIV;
        return s->private;
 }
 EXPORT_SYMBOL_GPL(comedi_alloc_spriv);
@@ -806,7 +806,6 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
                } else {
                        us->range_type = 0;     /* XXX */
                }
-               us->flags = s->flags;
 
                if (s->busy)
                        us->subd_flags |= SDF_BUSY;
@@ -818,8 +817,6 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
                        us->subd_flags |= SDF_LOCK_OWNER;
                if (!s->maxdata && s->maxdata_list)
                        us->subd_flags |= SDF_MAXDATA;
-               if (s->flaglist)
-                       us->subd_flags |= SDF_FLAGS;
                if (s->range_table_list)
                        us->subd_flags |= SDF_RANGETYPE;
                if (s->do_cmd)
@@ -829,8 +826,6 @@ static int do_subdinfo_ioctl(struct comedi_device *dev,
                        us->insn_bits_support = COMEDI_SUPPORTED;
                else
                        us->insn_bits_support = COMEDI_UNSUPPORTED;
-
-               us->settling_time_0 = s->settling_time_0;
        }
 
        ret = copy_to_user(arg, tmp, dev->n_subdevices * sizeof(*tmp));
@@ -875,13 +870,8 @@ static int do_chaninfo_ioctl(struct comedi_device *dev,
                        return -EFAULT;
        }
 
-       if (it.flaglist) {
-               if (!s->flaglist)
-                       return -EINVAL;
-               if (copy_to_user(it.flaglist, s->flaglist,
-                                s->n_chan * sizeof(unsigned int)))
-                       return -EFAULT;
-       }
+       if (it.flaglist)
+               return -EINVAL; /* flaglist not supported */
 
        if (it.rangelist) {
                int i;
@@ -1485,7 +1475,8 @@ static int do_cmd_ioctl(struct comedi_device *dev,
        if (async->cmd.flags & TRIG_WAKE_EOS)
                async->cb_mask |= COMEDI_CB_EOS;
 
-       comedi_set_subdevice_runflags(s, ~0, SRF_USER | SRF_RUNNING);
+       comedi_set_subdevice_runflags(s, SRF_USER | SRF_ERROR | SRF_RUNNING,
+                                     SRF_USER | SRF_RUNNING);
 
        /* set s->busy _after_ setting SRF_RUNNING flag to avoid race with
         * comedi_read() or comedi_write() */
index 2e19f659cd22ff828ceb056dc82bc644156e0913..143be8076a2e72361d11f88a2b64db8c4b89855b 100644 (file)
@@ -57,11 +57,6 @@ struct comedi_subdevice {
        unsigned int maxdata;   /* if maxdata==0, use list */
        const unsigned int *maxdata_list;       /* list is channel specific */
 
-       unsigned int flags;
-       const unsigned int *flaglist;
-
-       unsigned int settling_time_0;
-
        const struct comedi_lrange *range_table;
        const struct comedi_lrange *const *range_table_list;
 
@@ -307,7 +302,26 @@ static inline bool comedi_range_is_unipolar(struct comedi_subdevice *s,
        return s->range_table->range[range].min >= 0;
 }
 
-/* some silly little inline functions */
+static inline bool comedi_chan_range_is_bipolar(struct comedi_subdevice *s,
+                                               unsigned int chan,
+                                               unsigned int range)
+{
+       return s->range_table_list[chan]->range[range].min < 0;
+}
+
+static inline bool comedi_chan_range_is_unipolar(struct comedi_subdevice *s,
+                                                unsigned int chan,
+                                                unsigned int range)
+{
+       return s->range_table_list[chan]->range[range].min >= 0;
+}
+
+/* munge between offset binary and two's complement values */
+static inline unsigned int comedi_offset_munge(struct comedi_subdevice *s,
+                                              unsigned int val)
+{
+       return val ^ s->maxdata ^ (s->maxdata >> 1);
+}
 
 static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
 {
@@ -332,8 +346,8 @@ unsigned int comedi_buf_read_n_available(struct comedi_async *);
 unsigned int comedi_buf_read_alloc(struct comedi_async *, unsigned int);
 unsigned int comedi_buf_read_free(struct comedi_async *, unsigned int);
 
-int comedi_buf_put(struct comedi_async *, short);
-int comedi_buf_get(struct comedi_async *, short *);
+int comedi_buf_put(struct comedi_async *, unsigned short);
+int comedi_buf_get(struct comedi_async *, unsigned short *);
 
 void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
                          const void *source, unsigned int num_bytes);
@@ -345,6 +359,8 @@ void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
 int comedi_dio_insn_config(struct comedi_device *, struct comedi_subdevice *,
                           struct comedi_insn *, unsigned int *data,
                           unsigned int mask);
+unsigned int comedi_dio_update_state(struct comedi_subdevice *,
+                                    unsigned int *data);
 
 void *comedi_alloc_devpriv(struct comedi_device *, size_t);
 int comedi_alloc_subdevices(struct comedi_device *, int);
index 317a821b7906409a5fef8edd6a40b3360945300e..8f02bf66e20b2002b3b52655919a89f95c0fcad9 100644 (file)
@@ -190,6 +190,28 @@ int comedi_dio_insn_config(struct comedi_device *dev,
 }
 EXPORT_SYMBOL_GPL(comedi_dio_insn_config);
 
+/**
+ * comedi_dio_update_state() - update the internal state of DIO subdevices.
+ * @s: comedi_subdevice struct
+ * @data: the channel mask and bits to update
+ */
+unsigned int comedi_dio_update_state(struct comedi_subdevice *s,
+                                    unsigned int *data)
+{
+       unsigned int chanmask = (s->n_chan < 32) ? ((1 << s->n_chan) - 1)
+                                                : 0xffffffff;
+       unsigned int mask = data[0] & chanmask;
+       unsigned int bits = data[1];
+
+       if (mask) {
+               s->state &= ~mask;
+               s->state |= (bits & mask);
+       }
+
+       return mask;
+}
+EXPORT_SYMBOL_GPL(comedi_dio_update_state);
+
 static int insn_rw_emulate_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
                                struct comedi_insn *insn, unsigned int *data)
@@ -285,6 +307,13 @@ static int __comedi_device_postconfig(struct comedi_device *dev)
                if (s->type == COMEDI_SUBD_UNUSED)
                        continue;
 
+               if (s->type == COMEDI_SUBD_DO) {
+                       if (s->n_chan < 32)
+                               s->io_bits = (1 << s->n_chan) - 1;
+                       else
+                               s->io_bits = 0xffffffff;
+               }
+
                if (s->len_chanlist == 0)
                        s->len_chanlist = 1;
 
index 3abedcd2527bbb2aade465b75f0fe23f4918afdf..e3d737cf73029070248ff603b13ce89a6abf0c49 100644 (file)
 
 #include "../comedi.h"
 
+/*
+ * Common oscillator base values in nanoseconds
+ */
+#define I8254_OSC_BASE_10MHZ           100
+#define I8254_OSC_BASE_5MHZ            200
+#define I8254_OSC_BASE_4MHZ            250
+#define I8254_OSC_BASE_2MHZ            500
+#define I8254_OSC_BASE_1MHZ            1000
+
 #define i8253_cascade_ns_to_timer i8253_cascade_ns_to_timer_2div
 
 static inline void i8253_cascade_ns_to_timer_2div_old(int i8253_osc_base,
index 2f070fdbbb1d3b206b6e17f5f10bea0ec6e3a02a..b4009e863414ed87be35f2168921cf02e20caa67 100644 (file)
@@ -112,7 +112,7 @@ void subdev_8255_interrupt(struct comedi_device *dev,
 {
        struct subdev_8255_private *spriv = s->private;
        unsigned long iobase = spriv->iobase;
-       short d;
+       unsigned short d;
 
        d = spriv->io(0, _8255_DATA, 0, iobase);
        d |= (spriv->io(0, _8255_DATA + 1, 0, iobase) << 8);
@@ -126,30 +126,24 @@ EXPORT_SYMBOL_GPL(subdev_8255_interrupt);
 
 static int subdev_8255_insn(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
        struct subdev_8255_private *spriv = s->private;
        unsigned long iobase = spriv->iobase;
        unsigned int mask;
-       unsigned int bits;
        unsigned int v;
 
-       mask = data[0];
-       bits = data[1];
-
+       mask = comedi_dio_update_state(s, data);
        if (mask) {
-               v = s->state;
-               v &= ~mask;
-               v |= (bits & mask);
-
                if (mask & 0xff)
-                       spriv->io(1, _8255_DATA, v & 0xff, iobase);
+                       spriv->io(1, _8255_DATA, s->state & 0xff, iobase);
                if (mask & 0xff00)
-                       spriv->io(1, _8255_DATA + 1, (v >> 8) & 0xff, iobase);
+                       spriv->io(1, _8255_DATA + 1, (s->state >> 8) & 0xff,
+                                 iobase);
                if (mask & 0xff0000)
-                       spriv->io(1, _8255_DATA + 2, (v >> 16) & 0xff, iobase);
-
-               s->state = v;
+                       spriv->io(1, _8255_DATA + 2, (s->state >> 16) & 0xff,
+                                 iobase);
        }
 
        v = spriv->io(0, _8255_DATA, 0, iobase);
@@ -288,9 +282,6 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s,
        s->insn_bits    = subdev_8255_insn;
        s->insn_config  = subdev_8255_insn_config;
 
-       s->state        = 0;
-       s->io_bits      = 0;
-
        subdev_8255_do_config(dev, s);
 
        return 0;
index 63dff7729ea893e8e76ce2fdcad61ca50ebb9d45..dc87df032203746418fa7274b36be42c38617d3a 100644 (file)
@@ -204,7 +204,6 @@ static int addi_auto_attach(struct comedi_device *dev,
                s->len_chanlist =
                        devpriv->s_EeParameters.i_NbrDiChannel;
                s->range_table = &range_digital;
-               s->io_bits = 0; /* all bits input */
                s->insn_config = this_board->di_config;
                s->insn_read = this_board->di_read;
                s->insn_write = this_board->di_write;
@@ -223,7 +222,6 @@ static int addi_auto_attach(struct comedi_device *dev,
                s->len_chanlist =
                        devpriv->s_EeParameters.i_NbrDoChannel;
                s->range_table = &range_digital;
-               s->io_bits = 0xf;       /* all bits output */
 
                /* insn_config - for digital output memory */
                s->insn_config = this_board->do_config;
index dfd1e666cc18864191cab0536ddf99c0ee82f3b8..2ed2da3499f44a3c012c6b9bda78019bba1680a5 100644 (file)
@@ -133,7 +133,7 @@ struct addi_private {
        unsigned short us_UseDma;       /*  To use Dma or not */
        unsigned char b_DmaDoubleBuffer;        /*  we can use double buffering */
        unsigned int ui_DmaActualBuffer;        /*  which buffer is used now */
-       short *ul_DmaBufferVirtual[2];  /*  pointers to begin of DMA buffer */
+       unsigned short *ul_DmaBufferVirtual[2]; /*  pointers to DMA buffer */
        unsigned int ul_DmaBufferHw[2]; /*  hw address of DMA buff */
        unsigned int ui_DmaBufferSize[2];       /*  size of dma buffer in bytes */
        unsigned int ui_DmaBufferUsesize[2];    /*  which size we may now used for transfer */
index e3cc429403c08c35df09f02286a1079df039f0c9..84668544f52d79927fa0b664fad3aca6313bd361 100644 (file)
@@ -260,18 +260,13 @@ static int apci1564_do_insn_bits(struct comedi_device *dev,
                                 unsigned int *data)
 {
        struct addi_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
 
        s->state = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
                        APCI1564_DIGITAL_OP_RW);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
                        APCI1564_DIGITAL_OP_RW);
-       }
 
        data[1] = s->state;
 
index 1449b92403e249ff2e1198dfdcc2dece751105ee..3c9eec84f0eb557c25a5ea4bd82fdca4a15f515d 100644 (file)
@@ -1391,7 +1391,7 @@ static int i_APCI3120_CommandAnalogInput(struct comedi_device *dev,
  */
 static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,
                                                  struct comedi_subdevice *s,
-                                                 short *dma_buffer,
+                                                 unsigned short *dma_buffer,
                                                  unsigned int num_samples)
 {
        struct addi_private *devpriv = dev->private;
@@ -2175,21 +2175,16 @@ static int apci3120_do_insn_bits(struct comedi_device *dev,
                                 unsigned int *data)
 {
        struct addi_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-       unsigned int val;
 
-       /* The do channels are bits 7:4 of the do register */
-       val = devpriv->b_DigitalOutputRegister >> 4;
-       if (mask) {
-               val &= ~mask;
-               val |= (bits & mask);
-               devpriv->b_DigitalOutputRegister = val << 4;
+       if (comedi_dio_update_state(s, data)) {
+               /* The do channels are bits 7:4 of the do register */
+               devpriv->b_DigitalOutputRegister = s->state << 4;
 
-               outb(val << 4, devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
+               outb(devpriv->b_DigitalOutputRegister,
+                    devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
        }
 
-       data[1] = val;
+       data[1] = s->state;
 
        return insn->n;
 }
index 32dce0329fd5a1ab10d8a0c64ff162c538858812..dc73d4d348ed4fa9eb94635e2614e18102939de5 100644 (file)
@@ -623,16 +623,11 @@ static int apci3200_do_insn_bits(struct comedi_device *dev,
                                 unsigned int *data)
 {
        struct addi_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
 
        s->state = inl(devpriv->i_IobaseAddon) & 0xf;
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, devpriv->i_IobaseAddon);
-       }
 
        data[1] = s->state;
 
index 08674c18cf429052648b932c59ea7792bd44a47d..9d1b1425c60b7c8ec41f574df4f733687820c688 100644 (file)
@@ -90,16 +90,10 @@ static int apci1516_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inw(dev->iobase + APCI1516_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + APCI1516_DO_REG);
-       }
 
        data[1] = s->state;
 
index 96523744b8de57cc5203d7c7667b60f67f4b647c..5ee204bcbeef3a5577547c34d04c24f378b87464 100644 (file)
@@ -87,17 +87,8 @@ static int apci16xx_dio_insn_bits(struct comedi_device *dev,
                                  struct comedi_insn *insn,
                                  unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       /* Only update the channels configured as outputs */
-       mask &= s->io_bits;
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outl(s->state, dev->iobase + APCI16XX_OUT_REG(s->index));
-       }
 
        data[1] = inl(dev->iobase + APCI16XX_IN_REG(s->index));
 
index 6b0ea16ff5467eeb3da5c76a9c8a9f2c9c705faa..c77ee8732d38fe158f974a29ff5f0f2921afc609 100644 (file)
@@ -57,16 +57,10 @@ static int apci2032_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inl(dev->iobase + APCI2032_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, dev->iobase + APCI2032_DO_REG);
-       }
 
        data[1] = s->state;
 
index 92ac8ece8494b1e1998ed545ea62f89fb9d793c5..7fb32e778d8ba5742565c3aaf508557dca385807 100644 (file)
@@ -50,16 +50,10 @@ static int apci2200_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inw(dev->iobase + APCI2200_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + APCI2200_DO_REG);
-       }
 
        data[1] = s->state;
 
index d804957018aba8db2c0e95bd4f9d29a33ce8dfa0..67d09e8afb2efdbcf8c21677f884a135c59a5e8b 100644 (file)
@@ -164,7 +164,6 @@ static int apci3120_auto_attach(struct comedi_device *dev,
        s->maxdata = 1;
        s->len_chanlist = this_board->i_NbrDiChannel;
        s->range_table = &range_digital;
-       s->io_bits = 0; /* all bits input */
        s->insn_bits = apci3120_di_insn_bits;
 
        /*  Allocate and Initialise DO Subdevice Structures */
@@ -176,7 +175,6 @@ static int apci3120_auto_attach(struct comedi_device *dev,
        s->maxdata = this_board->i_DoMaxdata;
        s->len_chanlist = this_board->i_NbrDoChannel;
        s->range_table = &range_digital;
-       s->io_bits = 0xf;       /* all bits output */
        s->insn_bits = apci3120_do_insn_bits;
 
        /*  Allocate and Initialise Timer Subdevice Structures */
index d9650ffb7d2f3e99603535b1cf091df0db8b8b54..6138440b919e86dc94ea6c80f06c6573c079bb0b 100644 (file)
@@ -161,16 +161,10 @@ static int apci3501_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inl(dev->iobase + APCI3501_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, dev->iobase + APCI3501_DO_REG);
-       }
 
        data[1] = s->state;
 
index cf5dd10eaf91daa71cb75ced4270c450d49d31de..761cbf8f964b3c69b96c84baab5d9c21d7829454 100644 (file)
@@ -664,16 +664,10 @@ static int apci3xxx_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inl(dev->iobase + 48) & 0xf;
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, dev->iobase + 48);
-       }
 
        data[1] = s->state;
 
@@ -717,16 +711,11 @@ static int apci3xxx_dio_insn_bits(struct comedi_device *dev,
                                  struct comedi_insn *insn,
                                  unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
+       unsigned int mask;
        unsigned int val;
 
-       /* only update output channels */
-       mask &= s->io_bits;
+       mask = comedi_dio_update_state(s, data);
        if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
                if (mask & 0xff)
                        outl(s->state & 0xff, dev->iobase + 80);
                if (mask & 0xff0000)
index a67ad57cefcb906c108f044cd2c3c069bc788418..dd092c7954a9ef88e209b0f5392c6683b4618344 100644 (file)
@@ -1,44 +1,35 @@
 /*
-    comedi/drivers/adl_pci6208.c
-
-    Hardware driver for ADLink 6208 series cards:
-       card         | voltage output    | current output
-       -------------+-------------------+---------------
-       PCI-6208V    |  8 channels       | -
-       PCI-6216V    | 16 channels       | -
-       PCI-6208A    |  8 channels       | 8 channels
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
-    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.
-*/
+ * adl_pci6208.c
+ * Comedi driver for ADLink 6208 series cards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
+
 /*
-Driver: adl_pci6208
-Description: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards
-Devices: (ADLink) PCI-6208 [adl_pci6208]
-        (ADLink) PCI-6216 [adl_pci6216]
-Author: nsyeow <nsyeow@pd.jaring.my>
-Updated: Fri, 30 Jan 2004 14:44:27 +0800
-Status: untested
-
-Configuration Options: not applicable, uses PCI auto config
-
-References:
-       - ni_660x.c
-       - adl_pci9111.c         copied the entire pci setup section
-       - adl_pci9118.c
-*/
+ * Driver: adl_pci6208
+ * Description: ADLink PCI-6208/6216 Series Multi-channel Analog Output Cards
+ * Devices: (ADLink) PCI-6208 [adl_pci6208]
+ *         (ADLink) PCI-6216 [adl_pci6216]
+ * Author: nsyeow <nsyeow@pd.jaring.my>
+ * Updated: Fri, 30 Jan 2004 14:44:27 +0800
+ * Status: untested
+ *
+ * Configuration Options: not applicable, uses PCI auto config
+ */
 
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
 
 #include "../comedidev.h"
@@ -82,37 +73,56 @@ struct pci6208_private {
        unsigned int ao_readback[PCI6208_MAX_AO_CHANNELS];
 };
 
-static int pci6208_ao_winsn(struct comedi_device *dev,
-                           struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+static int pci6208_ao_wait_for_data_send(struct comedi_device *dev,
+                                        unsigned int timeout)
+{
+       unsigned int status;
+
+       while (timeout--) {
+               status = inw(dev->iobase + PCI6208_AO_STATUS);
+               if ((status & PCI6208_AO_STATUS_DATA_SEND) == 0)
+                       return 0;
+               udelay(1);
+       }
+
+       return -ETIME;
+}
+
+static int pci6208_ao_insn_write(struct comedi_device *dev,
+                                struct comedi_subdevice *s,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
        struct pci6208_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
-       unsigned long invert = 1 << (16 - 1);
-       unsigned long value = 0;
-       unsigned short status;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int val = devpriv->ao_readback[chan];
+       int ret;
        int i;
 
        for (i = 0; i < insn->n; i++) {
-               value = data[i] ^ invert;
+               val = data[i];
 
-               do {
-                       status = inw(dev->iobase + PCI6208_AO_STATUS);
-               } while (status & PCI6208_AO_STATUS_DATA_SEND);
+               /* D/A transfer rate is 2.2us, wait up to 10us */
+               ret = pci6208_ao_wait_for_data_send(dev, 10);
+               if (ret)
+                       return ret;
 
-               outw(value, dev->iobase + PCI6208_AO_CONTROL(chan));
+               /* the hardware expects two's complement values */
+               outw(comedi_offset_munge(s, val),
+                    dev->iobase + PCI6208_AO_CONTROL(chan));
        }
-       devpriv->ao_readback[chan] = value;
+       devpriv->ao_readback[chan] = val;
 
        return insn->n;
 }
 
-static int pci6208_ao_rinsn(struct comedi_device *dev,
-                           struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+static int pci6208_ao_insn_read(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
        struct pci6208_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
+       unsigned int chan = CR_CHAN(insn->chanspec);
        int i;
 
        for (i = 0; i < insn->n; i++)
@@ -141,15 +151,8 @@ static int pci6208_do_insn_bits(struct comedi_device *dev,
                                struct comedi_insn *insn,
                                unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + PCI6208_DIO);
-       }
 
        data[1] = s->state;
 
@@ -193,8 +196,8 @@ static int pci6208_auto_attach(struct comedi_device *dev,
        s->n_chan       = boardinfo->ao_chans;
        s->maxdata      = 0xffff;
        s->range_table  = &range_bipolar10;
-       s->insn_write   = pci6208_ao_winsn;
-       s->insn_read    = pci6208_ao_rinsn;
+       s->insn_write   = pci6208_ao_insn_write;
+       s->insn_read    = pci6208_ao_insn_read;
 
        s = &dev->subdevices[1];
        /* digital input subdevice */
@@ -221,10 +224,6 @@ static int pci6208_auto_attach(struct comedi_device *dev,
        val = inw(dev->iobase + PCI6208_DIO);
        val = (val & PCI6208_DIO_DO_MASK) >> PCI6208_DIO_DO_SHIFT;
        s->state        = val;
-       s->io_bits      = 0x0f;
-
-       dev_info(dev->class_dev, "%s: %s, I/O base=0x%04lx\n",
-               dev->driver->driver_name, dev->board_name, dev->iobase);
 
        return 0;
 }
@@ -259,5 +258,5 @@ static struct pci_driver adl_pci6208_pci_driver = {
 module_comedi_pci_driver(adl_pci6208_driver, adl_pci6208_pci_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for ADLink 6208 series cards");
 MODULE_LICENSE("GPL");
index 81b7203f824f15e7947b1f5783184171cdf10fc3..5617f5ca384a0bd8fd463c85dca28357bb025a2a 100644 (file)
@@ -112,21 +112,10 @@ static int adl_pci7x3x_do_insn_bits(struct comedi_device *dev,
                                    unsigned int *data)
 {
        unsigned long reg = (unsigned long)s->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                outl(s->state, dev->iobase + reg);
-       }
 
-       /*
-        * NOTE: The output register is not readable.
-        * This returned state will not be correct until all the
-        * outputs have been updated.
-        */
        data[1] = s->state;
 
        return insn->n;
index 78cea193504f3e772413298b25dca9bacb45a39b..eab8da2c3d66910b23ef26cc5fceac488843a114 100644 (file)
@@ -86,8 +86,6 @@ TODO:
 #define PCI9111_AI_INSTANT_READ_UDELAY_US      2
 #define PCI9111_AI_INSTANT_READ_TIMEOUT                100
 
-#define PCI9111_8254_CLOCK_PERIOD_NS           500
-
 /*
  * IO address map and bit defines
  */
@@ -153,7 +151,7 @@ struct pci9111_private_data {
        unsigned int div1;
        unsigned int div2;
 
-       short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
+       unsigned short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
 };
 
 static void plx9050_interrupt_control(unsigned long io_base,
@@ -393,11 +391,10 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev,
 
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
-                                              &dev_private->div1,
-                                              &dev_private->div2,
-                                              &cmd->convert_arg,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
+                                         &dev_private->div1,
+                                         &dev_private->div2,
+                                         &cmd->convert_arg, cmd->flags);
                if (tmp != cmd->convert_arg)
                        error++;
        }
@@ -570,7 +567,7 @@ static void pci9111_ai_munge(struct comedi_device *dev,
                             unsigned int num_bytes,
                             unsigned int start_chan_index)
 {
-       short *array = data;
+       unsigned short *array = data;
        unsigned int maxdata = s->maxdata;
        unsigned int invert = (maxdata + 1) >> 1;
        unsigned int shift = (maxdata == 0xffff) ? 0 : 4;
@@ -813,15 +810,8 @@ static int pci9111_do_insn_bits(struct comedi_device *dev,
                                struct comedi_insn *insn,
                                unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + PCI9111_DIO_REG);
-       }
 
        data[1] = s->state;
 
index 22196ada0362200b12f83d89e9bed0dfa208e83d..0f2e8591c6979e9ecf0c25be8ebe0be6fc99368f 100644 (file)
@@ -352,12 +352,11 @@ struct pci9118_private {
                                                 * on external start
                                                 */
        unsigned int ai_data_len;
-       short *ai_data;
-       short ao_data[2];                       /* data output buffer */
+       unsigned short ao_data[2];              /* data output buffer */
        unsigned int ai_scans;                  /* number of scans to do */
        char dma_doublebuf;                     /* we can use double buffering */
        unsigned int dma_actbuf;                /* which buffer is used now */
-       short *dmabuf_virt[2];                  /*
+       unsigned short *dmabuf_virt[2];                 /*
                                                 * pointers to begin of
                                                 * DMA buffer
                                                 */
@@ -671,13 +670,12 @@ static int pci9118_insn_bits_di(struct comedi_device *dev,
 
 static int pci9118_insn_bits_do(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data))
                outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
-       }
+
        data[1] = s->state;
 
        return insn->n;
@@ -701,7 +699,7 @@ static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
 
 static unsigned int defragment_dma_buffer(struct comedi_device *dev,
                                          struct comedi_subdevice *s,
-                                         short *dma_buffer,
+                                         unsigned short *dma_buffer,
                                          unsigned int num_samples)
 {
        struct pci9118_private *devpriv = dev->private;
@@ -725,7 +723,7 @@ static unsigned int defragment_dma_buffer(struct comedi_device *dev,
 
 static int move_block_from_dma(struct comedi_device *dev,
                                        struct comedi_subdevice *s,
-                                       short *dma_buffer,
+                                       unsigned short *dma_buffer,
                                        unsigned int num_samples)
 {
        struct pci9118_private *devpriv = dev->private;
@@ -793,7 +791,8 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
        case 4:
                if (*tim2 < this_board->ai_ns_min)
                        *tim2 = this_board->ai_ns_min;
-               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
+               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
+                                         div1, div2,
                                          tim2, flags & TRIG_ROUND_NEAREST);
                break;
        case 2:
@@ -925,7 +924,7 @@ static void pci9118_ai_munge(struct comedi_device *dev,
 {
        struct pci9118_private *devpriv = dev->private;
        unsigned int i, num_samples = num_bytes / sizeof(short);
-       short *array = data;
+       unsigned short *array = data;
 
        for (i = 0; i < num_samples; i++) {
                if (devpriv->usedma)
@@ -945,7 +944,7 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
                                           unsigned short int_daq)
 {
        struct pci9118_private *devpriv = dev->private;
-       register short sampl;
+       unsigned short sampl;
 
        s->async->events = 0;
 
@@ -1278,9 +1277,9 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
                tmp = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
-                                         &divisor2, &cmd->scan_begin_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                if (cmd->scan_begin_arg < this_board->ai_ns_min)
                        cmd->scan_begin_arg = this_board->ai_ns_min;
                if (tmp != cmd->scan_begin_arg)
@@ -1289,9 +1288,9 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (cmd->convert_arg < this_board->ai_ns_min)
                        cmd->convert_arg = this_board->ai_ns_min;
                if (tmp != cmd->convert_arg)
@@ -1613,7 +1612,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        devpriv->ai_n_chan = cmd->chanlist_len;
        devpriv->ai_n_scanlen = cmd->scan_end_arg;
        devpriv->ai_chanlist = cmd->chanlist;
-       devpriv->ai_data = s->async->prealloc_buf;
        devpriv->ai_data_len = s->async->prealloc_bufsz;
        devpriv->ai_timer1 = 0;
        devpriv->ai_timer2 = 0;
@@ -1987,8 +1985,8 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
                for (i = 0; i < 2; i++) {
                        for (pages = 4; pages >= 0; pages--) {
                                devpriv->dmabuf_virt[i] =
-                                   (short *)__get_free_pages(GFP_KERNEL,
-                                                             pages);
+                                   (unsigned short *)
+                                   __get_free_pages(GFP_KERNEL, pages);
                                if (devpriv->dmabuf_virt[i])
                                        break;
                        }
@@ -2075,7 +2073,6 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
        s->maxdata = 1;
        s->len_chanlist = 4;
        s->range_table = &range_digital;
-       s->io_bits = 0;         /* all bits input */
        s->insn_bits = pci9118_insn_bits_di;
 
        s = &dev->subdevices[3];
@@ -2085,11 +2082,10 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
        s->maxdata = 1;
        s->len_chanlist = 4;
        s->range_table = &range_digital;
-       s->io_bits = 0xf;       /* all bits output */
        s->insn_bits = pci9118_insn_bits_do;
 
        devpriv->valid = 1;
-       devpriv->i8254_osc_base = 250;  /* 250ns=4MHz */
+       devpriv->i8254_osc_base = I8254_OSC_BASE_4MHZ;
        devpriv->ai_maskharderr = 0x10a;
                                        /* default measure crash condition */
        if (hw_err_mask)                /* disable some requested */
index cdf5ba26c5904fdd93db071dc59c51addca83f7a..8150a67cd1fbf99927db2220dbb40bb0847c46b1 100644 (file)
@@ -119,7 +119,6 @@ struct adq12b_private {
        int differential;       /* option 3 of comedi_config */
        int last_channel;
        int last_range;
-       unsigned int digital_state;
 };
 
 /*
@@ -186,23 +185,25 @@ static int adq12b_di_insn_bits(struct comedi_device *dev,
 
 static int adq12b_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       struct adq12b_private *devpriv = dev->private;
-       int channel;
-
-       for (channel = 0; channel < 8; channel++)
-               if (((data[0] >> channel) & 0x01) != 0)
-                       outb((((data[1] >> channel) & 0x01) << 3) | channel,
-                            dev->iobase + ADQ12B_OUTBR);
-
-       /* store information to retrieve when asked for reading */
-       if (data[0]) {
-               devpriv->digital_state &= ~data[0];
-               devpriv->digital_state |= (data[0] & data[1]);
+       unsigned int mask;
+       unsigned int chan;
+       unsigned int val;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               for (chan = 0; chan < 8; chan++) {
+                       if ((mask >> chan) & 0x01) {
+                               val = (s->state >> chan) & 0x01;
+                               outb((val << 3) | chan,
+                                    dev->iobase + ADQ12B_OUTBR);
+                       }
+               }
        }
 
-       data[1] = devpriv->digital_state;
+       data[1] = s->state;
 
        return insn->n;
 }
@@ -223,7 +224,6 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
        devpriv->unipolar = it->options[1];
        devpriv->differential = it->options[2];
-       devpriv->digital_state = 0;
        /*
         * initialize channel and range to -1 so we make sure we
         * always write at least once to the CTREG in the instruction
index f84df46d326aeededa20d574bdcb8ae5b749a53f..c3fdcabe9aec6ac77626e0cecee123dc9d7c597e 100644 (file)
@@ -314,10 +314,9 @@ struct pci1710_private {
        unsigned int *ai_chanlist;      /*  actaul chanlist */
        unsigned int ai_flags;  /*  flaglist */
        unsigned int ai_data_len;       /*  len of data buffer */
-       short *ai_data;         /*  data buffer */
        unsigned int ai_timer1; /*  timers */
        unsigned int ai_timer2;
-       short ao_data[4];       /*  data output buffer */
+       unsigned short ao_data[4];      /*  data output buffer */
        unsigned int cnt0_write_wait;   /* after a write, wait for update of the
                                         * internal state */
 };
@@ -544,18 +543,14 @@ static int pci171x_insn_bits_di(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pci171x_insn_bits_do(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + PCI171x_DO);
-       }
+
        data[1] = s->state;
 
        return insn->n;
@@ -740,7 +735,7 @@ static void interrupt_pci1710_every_sample(void *d)
        int m;
 #ifdef PCI171x_PARANOIDCHECK
        const struct boardtype *this_board = comedi_board(dev);
-       short sampl;
+       unsigned short sampl;
 #endif
 
        m = inw(dev->iobase + PCI171x_STATUS);
@@ -821,7 +816,7 @@ static int move_block_from_fifo(struct comedi_device *dev,
        int i, j;
 #ifdef PCI171x_PARANOIDCHECK
        const struct boardtype *this_board = comedi_board(dev);
-       int sampl;
+       unsigned short sampl;
 #endif
 
        j = s->async->cur_chan;
@@ -1009,9 +1004,10 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
                } else {
                        devpriv->ai_et = 0;
                }
-               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
-                                         &divisor2, &devpriv->ai_timer1,
-                                         devpriv->ai_flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &devpriv->ai_timer1,
+                                         devpriv->ai_flags);
                outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
                if (mode != 2) {
                        /*  start pacer */
@@ -1090,9 +1086,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (cmd->convert_arg < this_board->ai_ns_min)
                        cmd->convert_arg = this_board->ai_ns_min;
                if (tmp != cmd->convert_arg)
@@ -1125,7 +1121,6 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        devpriv->ai_chanlist = cmd->chanlist;
        devpriv->ai_flags = cmd->flags;
        devpriv->ai_data_len = s->async->prealloc_bufsz;
-       devpriv->ai_data = s->async->prealloc_buf;
        devpriv->ai_timer1 = 0;
        devpriv->ai_timer2 = 0;
 
@@ -1288,7 +1283,7 @@ static int pci1710_auto_attach(struct comedi_device *dev,
                        s->do_cmdtest = pci171x_ai_cmdtest;
                        s->do_cmd = pci171x_ai_cmd;
                }
-               devpriv->i8254_osc_base = 100;  /*  100ns=10MHz */
+               devpriv->i8254_osc_base = I8254_OSC_BASE_10MHZ;
                subdev++;
        }
 
@@ -1320,7 +1315,6 @@ static int pci1710_auto_attach(struct comedi_device *dev,
                s->maxdata = 1;
                s->len_chanlist = this_board->n_dichan;
                s->range_table = &range_digital;
-               s->io_bits = 0; /* all bits input */
                s->insn_bits = pci171x_insn_bits_di;
                subdev++;
        }
@@ -1333,9 +1327,6 @@ static int pci1710_auto_attach(struct comedi_device *dev,
                s->maxdata = 1;
                s->len_chanlist = this_board->n_dochan;
                s->range_table = &range_digital;
-               /* all bits output */
-               s->io_bits = (1 << this_board->n_dochan) - 1;
-               s->state = 0;
                s->insn_bits = pci171x_insn_bits_do;
                subdev++;
        }
index b793d6987b843366654ac9935b0546ade9230f10..bd4f781b4b24a0ac66896c05f15b2c102f69f555 100644 (file)
@@ -105,7 +105,7 @@ TODO:
 
 struct pci1723_private {
        unsigned char da_range[8];      /* D/A output range for each channel */
-       short ao_data[8];       /* data output buffer */
+       unsigned short ao_data[8];      /* data output buffer */
 };
 
 /*
@@ -205,19 +205,16 @@ static int pci1723_dio_insn_config(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-  digital i/o bits read/write
-*/
 static int pci1723_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + PCI1723_WRITE_DIGITAL_OUTPUT_CMD);
-       }
+
        data[1] = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA);
+
        return insn->n;
 }
 
index f091fa0d304df6d54da515db639804faeb125a43..6bac665261f847c750299a9979bb140d7c83784c 100644 (file)
@@ -448,45 +448,39 @@ static int pci_dio_insn_bits_di_w(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pci_dio_insn_bits_do_b(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        const struct diosubd_data *d = (const struct diosubd_data *)s->private;
        int i;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                for (i = 0; i < d->regs; i++)
                        outb((s->state >> (8 * i)) & 0xff,
                             dev->iobase + d->addr + i);
        }
+
        data[1] = s->state;
 
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        const struct diosubd_data *d = (const struct diosubd_data *)s->private;
        int i;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                for (i = 0; i < d->regs; i++)
                        outw((s->state >> (16 * i)) & 0xffff,
                             dev->iobase + d->addr + 2 * i);
        }
+
        data[1] = s->state;
 
        return insn->n;
@@ -641,12 +635,10 @@ static int pci1760_insn_bits_di(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pci1760_insn_bits_do(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
        int ret;
        unsigned char omb[4] = {
@@ -657,14 +649,13 @@ static int pci1760_insn_bits_do(struct comedi_device *dev,
        };
        unsigned char imb[4];
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                omb[0] = s->state;
                ret = pci1760_mbxrequest(dev, omb, imb);
                if (!ret)
                        return ret;
        }
+
        data[1] = s->state;
 
        return insn->n;
index afe87cc897612c0508f0924088b65452533ad052..22b3dda135ff23a9b7ff351bba8c578227e90353 100644 (file)
@@ -45,9 +45,7 @@ static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
                                           struct comedi_insn *insn,
                                           unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       if (comedi_dio_update_state(s, data)) {
                outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
                outb((s->state >> 8) & 0xff,
                     dev->iobase + AIO_IIRO_16_RELAY_8_15);
index c1f723e8614613826d9753e07ec6af5044f925a7..2e4bf284d52c08e5edc7fbd6221563b01cd92e70 100644 (file)
@@ -941,31 +941,34 @@ static void dio200_subdev_8255_set_dir(struct comedi_device *dev,
        dio200_write8(dev, subpriv->ofs + 3, config);
 }
 
-/*
- * Handle 'insn_bits' for an '8255' DIO subdevice.
- */
 static int dio200_subdev_8255_bits(struct comedi_device *dev,
                                   struct comedi_subdevice *s,
-                                  struct comedi_insn *insn, unsigned int *data)
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
 {
        struct dio200_subdev_8255 *subpriv = s->private;
+       unsigned int mask;
+       unsigned int val;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-               if (data[0] & 0xff)
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               if (mask & 0xff)
                        dio200_write8(dev, subpriv->ofs, s->state & 0xff);
-               if (data[0] & 0xff00)
+               if (mask & 0xff00)
                        dio200_write8(dev, subpriv->ofs + 1,
                                      (s->state >> 8) & 0xff);
-               if (data[0] & 0xff0000)
+               if (mask & 0xff0000)
                        dio200_write8(dev, subpriv->ofs + 2,
                                      (s->state >> 16) & 0xff);
        }
-       data[1] = dio200_read8(dev, subpriv->ofs);
-       data[1] |= dio200_read8(dev, subpriv->ofs + 1) << 8;
-       data[1] |= dio200_read8(dev, subpriv->ofs + 2) << 16;
-       return 2;
+
+       val = dio200_read8(dev, subpriv->ofs);
+       val |= dio200_read8(dev, subpriv->ofs + 1) << 8;
+       val |= dio200_read8(dev, subpriv->ofs + 2) << 16;
+
+       data[1] = val;
+
+       return insn->n;
 }
 
 /*
@@ -1022,8 +1025,6 @@ static int dio200_subdev_8255_init(struct comedi_device *dev,
        s->maxdata = 1;
        s->insn_bits = dio200_subdev_8255_bits;
        s->insn_config = dio200_subdev_8255_config;
-       s->state = 0;
-       s->io_bits = 0;
        dio200_subdev_8255_set_dir(dev, s);
        return 0;
 }
index e7108045f5535969a695622697060a46c47a7e8b..5b4b5ab34e2e930869b854f0f7b4b2056b2dc526 100644 (file)
@@ -57,17 +57,16 @@ static const struct pc263_board pc263_boards[] = {
 
 static int pc263_do_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               /* Write out the new digital output lines */
-               outb(s->state & 0xFF, dev->iobase);
-               outb(s->state >> 8, dev->iobase + 1);
+       if (comedi_dio_update_state(s, data)) {
+               outb(s->state & 0xff, dev->iobase);
+               outb((s->state >> 8) & 0xff, dev->iobase + 1);
        }
+
+       data[1] = s->state;
+
        return insn->n;
 }
 
index 179de53a86f009cc69df7bb9be00067ac735e7d0..810e397d8fd7009a25f93c49cc0a076283af7fa7 100644 (file)
@@ -215,12 +215,6 @@ Caveats:
 #define CLK_EXT                7       /* external clock */
 /* Macro to construct clock input configuration register value. */
 #define CLK_CONFIG(chan, src)  ((((chan) & 3) << 3) | ((src) & 7))
-/* Timebases in ns. */
-#define TIMEBASE_10MHZ         100
-#define TIMEBASE_1MHZ          1000
-#define TIMEBASE_100KHZ                10000
-#define TIMEBASE_10KHZ         100000
-#define TIMEBASE_1KHZ          1000000
 
 /*
  * Counter/timer gate input configuration sources.
@@ -379,7 +373,7 @@ struct pci224_private {
        unsigned long state;
        spinlock_t ao_spinlock;
        unsigned int *ao_readback;
-       short *ao_scan_vals;
+       unsigned short *ao_scan_vals;
        unsigned char *ao_scan_order;
        int intr_cpuid;
        short intr_running;
@@ -843,26 +837,26 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
                switch (round_mode) {
                case TRIG_ROUND_NEAREST:
                default:
-                       round = TIMEBASE_10MHZ / 2;
+                       round = I8254_OSC_BASE_10MHZ / 2;
                        break;
                case TRIG_ROUND_DOWN:
                        round = 0;
                        break;
                case TRIG_ROUND_UP:
-                       round = TIMEBASE_10MHZ - 1;
+                       round = I8254_OSC_BASE_10MHZ - 1;
                        break;
                }
                /* Be careful to avoid overflow! */
-               div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
-               div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
-                   TIMEBASE_10MHZ;
+               div2 = cmd->scan_begin_arg / I8254_OSC_BASE_10MHZ;
+               div2 += (round + cmd->scan_begin_arg % I8254_OSC_BASE_10MHZ) /
+                       I8254_OSC_BASE_10MHZ;
                if (div2 <= 0x10000) {
                        /* A single timer will suffice. */
                        if (div2 < 2)
                                div2 = 2;
-                       cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
+                       cmd->scan_begin_arg = div2 * I8254_OSC_BASE_10MHZ;
                        if (cmd->scan_begin_arg < div2 ||
-                           cmd->scan_begin_arg < TIMEBASE_10MHZ) {
+                           cmd->scan_begin_arg < I8254_OSC_BASE_10MHZ) {
                                /* Overflow! */
                                cmd->scan_begin_arg = MAX_SCAN_PERIOD;
                        }
@@ -870,7 +864,8 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
                        /* Use two timers. */
                        div1 = devpriv->cached_div1;
                        div2 = devpriv->cached_div2;
-                       pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
+                       pci224_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                                  &div1, &div2,
                                                   &cmd->scan_begin_arg,
                                                   round_mode);
                        devpriv->cached_div1 = div1;
@@ -1002,19 +997,19 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                switch (round_mode) {
                case TRIG_ROUND_NEAREST:
                default:
-                       round = TIMEBASE_10MHZ / 2;
+                       round = I8254_OSC_BASE_10MHZ / 2;
                        break;
                case TRIG_ROUND_DOWN:
                        round = 0;
                        break;
                case TRIG_ROUND_UP:
-                       round = TIMEBASE_10MHZ - 1;
+                       round = I8254_OSC_BASE_10MHZ - 1;
                        break;
                }
                /* Be careful to avoid overflow! */
-               div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
-               div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
-                   TIMEBASE_10MHZ;
+               div2 = cmd->scan_begin_arg / I8254_OSC_BASE_10MHZ;
+               div2 += (round + cmd->scan_begin_arg % I8254_OSC_BASE_10MHZ) /
+                       I8254_OSC_BASE_10MHZ;
                if (div2 <= 0x10000) {
                        /* A single timer will suffice. */
                        if (div2 < 2)
@@ -1025,7 +1020,8 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                        /* Use two timers. */
                        div1 = devpriv->cached_div1;
                        div2 = devpriv->cached_div2;
-                       pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
+                       pci224_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                                  &div1, &div2,
                                                   &ns, round_mode);
                }
 
@@ -1116,7 +1112,7 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
        const struct pci224_board *thisboard = comedi_board(dev);
        struct pci224_private *devpriv = dev->private;
        struct comedi_async *async = s->async;
-       short *array = data;
+       unsigned short *array = data;
        unsigned int length = num_bytes / sizeof(*array);
        unsigned int offset;
        unsigned int shift;
index 43059c25d5ea1ac8f89d1b0dbe30d35126a7dc36..a97bbd6ca3db5a5a3b6945c5157c25082ac62165 100644 (file)
@@ -573,14 +573,14 @@ static const struct comedi_lrange pci230_ao_range = { 2, {
 /* PCI230 daccon bipolar flag for each analogue output range. */
 static const unsigned char pci230_ao_bipolar[2] = { 0, 1 };
 
-static short pci230_ai_read(struct comedi_device *dev)
+static unsigned short pci230_ai_read(struct comedi_device *dev)
 {
        const struct pci230_board *thisboard = comedi_board(dev);
        struct pci230_private *devpriv = dev->private;
-       short data;
+       unsigned short data;
 
        /* Read sample. */
-       data = (short)inw(dev->iobase + PCI230_ADCDATA);
+       data = inw(dev->iobase + PCI230_ADCDATA);
        /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
         * four bits reserved for expansion). */
        /* PCI230+ is 16 bit AI. */
@@ -595,7 +595,7 @@ static short pci230_ai_read(struct comedi_device *dev)
 }
 
 static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
-                                                   short datum)
+                                                   unsigned short datum)
 {
        const struct pci230_board *thisboard = comedi_board(dev);
        struct pci230_private *devpriv = dev->private;
@@ -609,11 +609,12 @@ static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
         * four bits reserved for expansion). */
        /* PCI230+ is also 12 bit AO. */
        datum <<= (16 - thisboard->ao_bits);
-       return (unsigned short)datum;
+       return datum;
 }
 
 static inline void pci230_ao_write_nofifo(struct comedi_device *dev,
-                                         short datum, unsigned int chan)
+                                         unsigned short datum,
+                                         unsigned int chan)
 {
        struct pci230_private *devpriv = dev->private;
 
@@ -627,8 +628,8 @@ static inline void pci230_ao_write_nofifo(struct comedi_device *dev,
                                                                PCI230_DACOUT2));
 }
 
-static inline void pci230_ao_write_fifo(struct comedi_device *dev, short datum,
-                                       unsigned int chan)
+static inline void pci230_ao_write_fifo(struct comedi_device *dev,
+                                       unsigned short datum, unsigned int chan)
 {
        struct pci230_private *devpriv = dev->private;
 
@@ -1165,7 +1166,7 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev,
                                    struct comedi_subdevice *s)
 {
        struct pci230_private *devpriv = dev->private;
-       short data;
+       unsigned short data;
        int i, ret;
        struct comedi_async *async = s->async;
        struct comedi_cmd *cmd = &async->cmd;
@@ -1258,7 +1259,7 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev,
                /* Process scans. */
                for (n = 0; n < num_scans; n++) {
                        for (i = 0; i < cmd->chanlist_len; i++) {
-                               short datum;
+                               unsigned short datum;
 
                                comedi_buf_get(async, &datum);
                                pci230_ao_write_fifo(dev, datum,
index 145bb48f618e9ab1516a8881f2c0f13c4bb795c2..4bd4ef8e88cd05dbf6453fb88f988196c5eb5174 100644 (file)
@@ -44,17 +44,16 @@ The state of the outputs can be read.
 
 static int pci263_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               /* Write out the new digital output lines */
-               outb(s->state & 0xFF, dev->iobase);
-               outb(s->state >> 8, dev->iobase + 1);
+       if (comedi_dio_update_state(s, data)) {
+               outb(s->state & 0xff, dev->iobase);
+               outb((s->state >> 8) & 0xff, dev->iobase + 1);
        }
+
+       data[1] = s->state;
+
        return insn->n;
 }
 
index 0ce93da70847c566fd328ae21ae80f258fade0f1..64d5f291553fb46a04f94154a6c20973c8af812f 100644 (file)
@@ -234,9 +234,9 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev,
                unsigned int div1 = 0, div2 = 0;
 
                tmp = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer(100, &div1, &div2,
-                                         &cmd->scan_begin_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &div1, &div2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                if (tmp != cmd->scan_begin_arg)
                        err++;
        }
@@ -244,9 +244,9 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev,
                unsigned int div1 = 0, div2 = 0;
 
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer(100, &div1, &div2,
-                                         &cmd->scan_begin_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &div1, &div2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                if (tmp != cmd->convert_arg)
                        err++;
                if (cmd->scan_begin_src == TRIG_TIMER &&
@@ -325,14 +325,11 @@ static int das16cs_ao_rinsn(struct comedi_device *dev,
 
 static int das16cs_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + DAS16CS_DIO);
-       }
 
        data[1] = inw(dev->iobase + DAS16CS_DIO);
 
index 41d89ee7fa33078e53203ea52739211c89646e6d..e72a403db17ca8e0f0d7715791ef1ff8d27223b0 100644 (file)
@@ -73,7 +73,6 @@ analog triggering on 1602 series
 #include "amcc_s5933.h"
 #include "comedi_fc.h"
 
-#define TIMER_BASE             100     /* 10MHz master clock */
 #define AI_BUFFER_SIZE         1024    /* max ai fifo size */
 #define AO_BUFFER_SIZE         1024    /* max ao fifo size */
 #define NUM_CHANNELS_8800      8
@@ -358,15 +357,15 @@ struct cb_pcidas_private {
        unsigned int s5933_intcsr_bits;
        unsigned int ao_control_bits;
        /* fifo buffers */
-       short ai_buffer[AI_BUFFER_SIZE];
-       short ao_buffer[AO_BUFFER_SIZE];
+       unsigned short ai_buffer[AI_BUFFER_SIZE];
+       unsigned short ao_buffer[AO_BUFFER_SIZE];
        /* divisors of master clock for analog output pacing */
        unsigned int ao_divisor1;
        unsigned int ao_divisor2;
        /* number of analog output samples remaining */
        unsigned int ao_count;
        /* cached values for readback */
-       int ao_value[2];
+       unsigned short ao_value[2];
        unsigned int caldac_value[NUM_CHANNELS_8800];
        unsigned int trimpot_value[NUM_CHANNELS_8402];
        unsigned int dac08_value;
@@ -880,21 +879,19 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
                tmp = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &(devpriv->divisor1),
-                                              &(devpriv->divisor2),
-                                              &(cmd->scan_begin_arg),
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                if (tmp != cmd->scan_begin_arg)
                        err++;
        }
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &(devpriv->divisor1),
-                                              &(devpriv->divisor2),
-                                              &(cmd->convert_arg),
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (tmp != cmd->convert_arg)
                        err++;
        }
@@ -932,9 +929,9 @@ static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
 {
        struct cb_pcidas_private *devpriv = dev->private;
 
-       i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
-                                      &(devpriv->divisor2), ns,
-                                      rounding_flags & TRIG_ROUND_MASK);
+       i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                 &devpriv->divisor1, &devpriv->divisor2,
+                                 ns, rounding_flags);
 
        /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
        i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
@@ -1084,11 +1081,10 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
                tmp = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &(devpriv->ao_divisor1),
-                                              &(devpriv->ao_divisor2),
-                                              &(cmd->scan_begin_arg),
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &devpriv->ao_divisor1,
+                                         &devpriv->ao_divisor2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                if (tmp != cmd->scan_begin_arg)
                        err++;
        }
@@ -1209,11 +1205,10 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev,
 
        /*  load counters */
        if (cmd->scan_begin_src == TRIG_TIMER) {
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &(devpriv->ao_divisor1),
-                                              &(devpriv->ao_divisor2),
-                                              &(cmd->scan_begin_arg),
-                                              cmd->flags);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &devpriv->ao_divisor1,
+                                         &devpriv->ao_divisor2,
+                                         &cmd->scan_begin_arg, cmd->flags);
 
                /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
                i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
index 388dbd7a5d27f2fa1c93b24f4f2342558f4b0b8c..ff5206536be36c3c4013efce6ca5fd9081f32ae0 100644 (file)
@@ -1137,7 +1137,7 @@ struct pcidas64_private {
        volatile short ai_cmd_running;
        unsigned int ai_fifo_segment_length;
        struct ext_clock_info ext_clock;
-       short ao_bounce_buffer[DAC_FIFO_SIZE];
+       unsigned short ao_bounce_buffer[DAC_FIFO_SIZE];
 };
 
 static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
@@ -3490,18 +3490,15 @@ static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
        return insn->n;
 }
 
-static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
-                   struct comedi_insn *insn, unsigned int *data)
+static int do_wbits(struct comedi_device *dev,
+                   struct comedi_subdevice *s,
+                   struct comedi_insn *insn,
+                   unsigned int *data)
 {
        struct pcidas64_private *devpriv = dev->private;
 
-       data[0] &= 0xf;
-       /*  zero bits we are going to change */
-       s->state &= ~data[0];
-       /*  set new bits */
-       s->state |= data[0] & data[1];
-
-       writeb(s->state, devpriv->dio_counter_iobase + DO_REG);
+       if (comedi_dio_update_state(s, data))
+               writeb(s->state, devpriv->dio_counter_iobase + DO_REG);
 
        data[1] = s->state;
 
@@ -3526,14 +3523,14 @@ static int dio_60xx_config_insn(struct comedi_device *dev,
        return insn->n;
 }
 
-static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int dio_60xx_wbits(struct comedi_device *dev,
+                         struct comedi_subdevice *s,
+                         struct comedi_insn *insn,
+                         unsigned int *data)
 {
        struct pcidas64_private *devpriv = dev->private;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                writeb(s->state,
                       devpriv->dio_counter_iobase + DIO_DATA_60XX_REG);
        }
index a4dea7cb86bef30294574aa42299793b70eb0308..8558b07f8df3a0bd07267fcfdc7eb0e8d40e4fb2 100644 (file)
@@ -30,7 +30,7 @@ extern unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd,
                                              unsigned int num_bytes);
 
 static inline unsigned int cfc_write_to_buffer(struct comedi_subdevice *subd,
-                                              short data)
+                                              unsigned short data)
 {
        return cfc_write_array_to_buffer(subd, &data, sizeof(data));
 };
index f28a15f0274e44819040d7322d046f43aab03c05..9de81c7712fb9103ae9054f54b37abf4dfa2c0b8 100644 (file)
 /*
-    comedi/drivers/comedi_parport.c
-    hardware driver for standard parallel port
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1998,2001 David A. Schleef <ds@schleef.org>
-
-    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.
-*/
-/*
-Driver: comedi_parport
-Description: Standard PC parallel port
-Author: ds
-Status: works in immediate mode
-Devices: [standard] parallel port (comedi_parport)
-Updated: Tue, 30 Apr 2002 21:11:45 -0700
-
-A cheap and easy way to get a few more digital I/O lines.  Steal
-additional parallel ports from old computers or your neighbors'
-computers.
-
-Option list:
- 0: I/O port base for the parallel port.
- 1: IRQ
-
-Parallel Port Lines:
-
-pin     subdev  chan    aka
----     ------  ----    ---
-1       2       0       strobe
-2       0       0       data 0
-3       0       1       data 1
-4       0       2       data 2
-5       0       3       data 3
-6       0       4       data 4
-7       0       5       data 5
-8       0       6       data 6
-9       0       7       data 7
-10      1       3       acknowledge
-11      1       4       busy
-12      1       2       output
-13      1       1       printer selected
-14      2       1       auto LF
-15      1       0       error
-16      2       2       init
-17      2       3       select printer
-18-25   ground
-
-Notes:
-
-Subdevices 0 is digital I/O, subdevice 1 is digital input, and
-subdevice 2 is digital output.  Unlike other Comedi devices,
-subdevice 0 defaults to output.
-
-Pins 13 and 14 are inverted once by Comedi and once by the
-hardware, thus cancelling the effect.
-
-Pin 1 is a strobe, thus acts like one.  There's no way in software
-to change this, at least on a standard parallel port.
-
-Subdevice 3 pretends to be a digital input subdevice, but it always
-returns 0 when read.  However, if you run a command with
-scan_begin_src=TRIG_EXT, it uses pin 10 as a external triggering
-pin, which can be used to wake up tasks.
-*/
+ * comedi_parport.c
+ * Comedi driver for standard parallel port
+ *
+ * For more information see:
+ *     http://retired.beyondlogic.org/spp/parallel.htm
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1998,2001 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
+
 /*
-   see http://www.beyondlogic.org/ for information.
-   or http://www.linux-magazin.de/ausgabe/1999/10/IO/io.html
+ * Driver: comedi_parport
+ * Description: Standard PC parallel port
+ * Author: ds
+ * Status: works in immediate mode
+ * Devices: (standard) parallel port [comedi_parport]
+ * Updated: Tue, 30 Apr 2002 21:11:45 -0700
+ *
+ * A cheap and easy way to get a few more digital I/O lines. Steal
+ * additional parallel ports from old computers or your neighbors'
+ * computers.
+ *
+ * Option list:
+ *   0: I/O port base for the parallel port.
+ *   1: IRQ (optional)
+ *
+ * Parallel Port Lines:
+ *
+ *      pin   subdev  chan  type  name
+ *     -----  ------  ----  ----  --------------
+ *       1      2       0    DO   strobe
+ *       2      0       0    DIO  data 0
+ *       3      0       1    DIO  data 1
+ *       4      0       2    DIO  data 2
+ *       5      0       3    DIO  data 3
+ *       6      0       4    DIO  data 4
+ *       7      0       5    DIO  data 5
+ *       8      0       6    DIO  data 6
+ *       9      0       7    DIO  data 7
+ *      10      1       3    DI   ack
+ *      11      1       4    DI   busy
+ *      12      1       2    DI   paper out
+ *      13      1       1    DI   select in
+ *      14      2       1    DO   auto LF
+ *      15      1       0    DI   error
+ *      16      2       2    DO   init
+ *      17      2       3    DO   select printer
+ *     18-25                      ground
+ *
+ * When an IRQ is configured subdevice 3 pretends to be a digital
+ * input subdevice, but it always returns 0 when read. However, if
+ * you run a command with scan_begin_src=TRIG_EXT, it uses pin 10
+ * as a external trigger, which can be used to wake up tasks.
  */
 
 #include <linux/module.h>
-#include "../comedidev.h"
 #include <linux/interrupt.h>
 
-#include "comedi_fc.h"
-
-#define PARPORT_SIZE 3
-
-#define PARPORT_A 0
-#define PARPORT_B 1
-#define PARPORT_C 2
+#include "../comedidev.h"
 
-struct parport_private {
-       unsigned int a_data;
-       unsigned int c_data;
-       int enable_irq;
-};
+#include "comedi_fc.h"
 
-static int parport_insn_a(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+/*
+ * Register map
+ */
+#define PARPORT_DATA_REG       0x00
+#define PARPORT_STATUS_REG     0x01
+#define PARPORT_CTRL_REG       0x02
+#define PARPORT_CTRL_IRQ_ENA   (1 << 4)
+#define PARPORT_CTRL_BIDIR_ENA (1 << 5)
+
+static int parport_data_reg_insn_bits(struct comedi_device *dev,
+                                     struct comedi_subdevice *s,
+                                     struct comedi_insn *insn,
+                                     unsigned int *data)
 {
-       struct parport_private *devpriv = dev->private;
-
-       if (data[0]) {
-               devpriv->a_data &= ~data[0];
-               devpriv->a_data |= (data[0] & data[1]);
-
-               outb(devpriv->a_data, dev->iobase + PARPORT_A);
-       }
+       if (comedi_dio_update_state(s, data))
+               outb(s->state, dev->iobase + PARPORT_DATA_REG);
 
-       data[1] = inb(dev->iobase + PARPORT_A);
+       data[1] = inb(dev->iobase + PARPORT_DATA_REG);
 
        return insn->n;
 }
 
-static int parport_insn_config_a(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+static int parport_data_reg_insn_config(struct comedi_device *dev,
+                                       struct comedi_subdevice *s,
+                                       struct comedi_insn *insn,
+                                       unsigned int *data)
 {
-       struct parport_private *devpriv = dev->private;
-
-       if (data[0]) {
-               s->io_bits = 0xff;
-               devpriv->c_data &= ~(1 << 5);
-       } else {
-               s->io_bits = 0;
-               devpriv->c_data |= (1 << 5);
-       }
-       outb(devpriv->c_data, dev->iobase + PARPORT_C);
+       unsigned int ctrl;
+       int ret;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0xff);
+       if (ret)
+               return ret;
+
+       ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
+       if (s->io_bits)
+               ctrl &= ~PARPORT_CTRL_BIDIR_ENA;
+       else
+               ctrl |= PARPORT_CTRL_BIDIR_ENA;
+       outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
 
-       return 1;
+       return insn->n;
 }
 
-static int parport_insn_b(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int parport_status_reg_insn_bits(struct comedi_device *dev,
+                                       struct comedi_subdevice *s,
+                                       struct comedi_insn *insn,
+                                       unsigned int *data)
 {
-       if (data[0]) {
-               /* should writes be ignored? */
-               /* anyone??? */
-       }
-
-       data[1] = (inb(dev->iobase + PARPORT_B) >> 3);
+       data[1] = inb(dev->iobase + PARPORT_STATUS_REG) >> 3;
 
        return insn->n;
 }
 
-static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int parport_ctrl_reg_insn_bits(struct comedi_device *dev,
+                                     struct comedi_subdevice *s,
+                                     struct comedi_insn *insn,
+                                     unsigned int *data)
 {
-       struct parport_private *devpriv = dev->private;
-
-       data[0] &= 0x0f;
-       if (data[0]) {
-               devpriv->c_data &= ~data[0];
-               devpriv->c_data |= (data[0] & data[1]);
+       unsigned int ctrl;
 
-               outb(devpriv->c_data, dev->iobase + PARPORT_C);
+       if (comedi_dio_update_state(s, data)) {
+               ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
+               ctrl &= (PARPORT_CTRL_IRQ_ENA | PARPORT_CTRL_BIDIR_ENA);
+               ctrl |= s->state;
+               outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
        }
 
-       data[1] = devpriv->c_data & 0xf;
+       data[1] = s->state;
 
        return insn->n;
 }
 
-static int parport_intr_insn(struct comedi_device *dev,
-                            struct comedi_subdevice *s,
-                            struct comedi_insn *insn, unsigned int *data)
+static int parport_intr_insn_bits(struct comedi_device *dev,
+                                 struct comedi_subdevice *s,
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        data[1] = 0;
        return insn->n;
@@ -213,12 +198,11 @@ static int parport_intr_cmdtest(struct comedi_device *dev,
 static int parport_intr_cmd(struct comedi_device *dev,
                            struct comedi_subdevice *s)
 {
-       struct parport_private *devpriv = dev->private;
+       unsigned int ctrl;
 
-       devpriv->c_data |= 0x10;
-       outb(devpriv->c_data, dev->iobase + PARPORT_C);
-
-       devpriv->enable_irq = 1;
+       ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
+       ctrl |= PARPORT_CTRL_IRQ_ENA;
+       outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
 
        return 0;
 }
@@ -226,12 +210,11 @@ static int parport_intr_cmd(struct comedi_device *dev,
 static int parport_intr_cancel(struct comedi_device *dev,
                               struct comedi_subdevice *s)
 {
-       struct parport_private *devpriv = dev->private;
-
-       devpriv->c_data &= ~0x10;
-       outb(devpriv->c_data, dev->iobase + PARPORT_C);
+       unsigned int ctrl;
 
-       devpriv->enable_irq = 0;
+       ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
+       ctrl &= ~PARPORT_CTRL_IRQ_ENA;
+       outb(ctrl, dev->iobase + PARPORT_CTRL_REG);
 
        return 0;
 }
@@ -239,10 +222,11 @@ static int parport_intr_cancel(struct comedi_device *dev,
 static irqreturn_t parport_interrupt(int irq, void *d)
 {
        struct comedi_device *dev = d;
-       struct parport_private *devpriv = dev->private;
-       struct comedi_subdevice *s = &dev->subdevices[3];
+       struct comedi_subdevice *s = dev->read_subdev;
+       unsigned int ctrl;
 
-       if (!devpriv->enable_irq)
+       ctrl = inb(dev->iobase + PARPORT_CTRL_REG);
+       if (!(ctrl & PARPORT_CTRL_IRQ_ENA))
                return IRQ_NONE;
 
        comedi_buf_put(s->async, 0);
@@ -255,79 +239,69 @@ static irqreturn_t parport_interrupt(int irq, void *d)
 static int parport_attach(struct comedi_device *dev,
                          struct comedi_devconfig *it)
 {
-       struct parport_private *devpriv;
        struct comedi_subdevice *s;
-       unsigned int irq;
        int ret;
 
-       ret = comedi_request_region(dev, it->options[0], PARPORT_SIZE);
+       ret = comedi_request_region(dev, it->options[0], 0x03);
        if (ret)
                return ret;
 
-       irq = it->options[1];
-       if (irq) {
-               ret = request_irq(irq, parport_interrupt, 0, dev->board_name,
-                                 dev);
-               if (ret < 0) {
-                       dev_err(dev->class_dev, "irq not available\n");
-                       return -EINVAL;
-               }
-               dev->irq = irq;
+       if (it->options[1]) {
+               ret = request_irq(it->options[1], parport_interrupt, 0,
+                                 dev->board_name, dev);
+               if (ret == 0)
+                       dev->irq = it->options[1];
        }
 
-       ret = comedi_alloc_subdevices(dev, 4);
+       ret = comedi_alloc_subdevices(dev, dev->irq ? 4 : 3);
        if (ret)
                return ret;
 
-       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-       if (!devpriv)
-               return -ENOMEM;
-
+       /* Digial I/O subdevice - Parallel port DATA register */
        s = &dev->subdevices[0];
-       s->type = COMEDI_SUBD_DIO;
-       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-       s->n_chan = 8;
-       s->maxdata = 1;
-       s->range_table = &range_digital;
-       s->insn_bits = parport_insn_a;
-       s->insn_config = parport_insn_config_a;
-
+       s->type         = COMEDI_SUBD_DIO;
+       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+       s->n_chan       = 8;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = parport_data_reg_insn_bits;
+       s->insn_config  = parport_data_reg_insn_config;
+
+       /* Digial Input subdevice - Parallel port STATUS register */
        s = &dev->subdevices[1];
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE;
-       s->n_chan = 5;
-       s->maxdata = 1;
-       s->range_table = &range_digital;
-       s->insn_bits = parport_insn_b;
-
+       s->type         = COMEDI_SUBD_DI;
+       s->subdev_flags = SDF_READABLE;
+       s->n_chan       = 5;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = parport_status_reg_insn_bits;
+
+       /* Digial Output subdevice - Parallel port CONTROL register */
        s = &dev->subdevices[2];
-       s->type = COMEDI_SUBD_DO;
-       s->subdev_flags = SDF_WRITABLE;
-       s->n_chan = 4;
-       s->maxdata = 1;
-       s->range_table = &range_digital;
-       s->insn_bits = parport_insn_c;
-
-       s = &dev->subdevices[3];
-       if (irq) {
+       s->type         = COMEDI_SUBD_DO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = 4;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = parport_ctrl_reg_insn_bits;
+
+       if (dev->irq) {
+               /* Digial Input subdevice - Interrupt support */
+               s = &dev->subdevices[3];
                dev->read_subdev = s;
-               s->type = COMEDI_SUBD_DI;
-               s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
-               s->n_chan = 1;
-               s->maxdata = 1;
-               s->range_table = &range_digital;
-               s->insn_bits = parport_intr_insn;
-               s->do_cmdtest = parport_intr_cmdtest;
-               s->do_cmd = parport_intr_cmd;
-               s->cancel = parport_intr_cancel;
-       } else {
-               s->type = COMEDI_SUBD_UNUSED;
+               s->type         = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+               s->n_chan       = 1;
+               s->maxdata      = 1;
+               s->range_table  = &range_digital;
+               s->insn_bits    = parport_intr_insn_bits;
+               s->do_cmdtest   = parport_intr_cmdtest;
+               s->do_cmd       = parport_intr_cmd;
+               s->cancel       = parport_intr_cancel;
        }
 
-       devpriv->a_data = 0;
-       outb(devpriv->a_data, dev->iobase + PARPORT_A);
-       devpriv->c_data = 0;
-       outb(devpriv->c_data, dev->iobase + PARPORT_C);
+       outb(0, dev->iobase + PARPORT_DATA_REG);
+       outb(0, dev->iobase + PARPORT_CTRL_REG);
 
        return 0;
 }
@@ -341,5 +315,5 @@ static struct comedi_driver parport_driver = {
 module_comedi_driver(parport_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi: Standard parallel port driver");
 MODULE_LICENSE("GPL");
index e781716bf3555e9a93b3af8e7bb5a11ac12c35da..89836c0828d9cb08a8626cecbe9fd266bf38f9d2 100644 (file)
@@ -40,17 +40,11 @@ Configuration Options: not applicable, uses comedi PCI auto config
 
 static int contec_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + PIO1616L_DO_REG);
-       }
 
        data[1] = s->state;
 
index 5f669709501f90376afe046e84bda819f1544f2d..15dd33e3e1c796c12f2f409a77da22395c4c6c48 100644 (file)
@@ -279,27 +279,23 @@ static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
        return insn->n;
 }
 
-static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int das08_do_wbits(struct comedi_device *dev,
+                         struct comedi_subdevice *s,
+                         struct comedi_insn *insn,
+                         unsigned int *data)
 {
        struct das08_private_struct *devpriv = dev->private;
-       int wbits;
-
-       /*  get current settings of digital output lines */
-       wbits = (devpriv->do_mux_bits >> 4) & 0xf;
-       /*  null bits we are going to set */
-       wbits &= ~data[0];
-       /*  set new bit values */
-       wbits |= data[0] & data[1];
-       /*  remember digital output bits */
-       /*  prevent race with setting of analog input mux */
-       spin_lock(&dev->spinlock);
-       devpriv->do_mux_bits &= ~DAS08_DO_MASK;
-       devpriv->do_mux_bits |= DAS08_OP(wbits);
-       outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL);
-       spin_unlock(&dev->spinlock);
 
-       data[1] = wbits;
+       if (comedi_dio_update_state(s, data)) {
+               /* prevent race with setting of analog input mux */
+               spin_lock(&dev->spinlock);
+               devpriv->do_mux_bits &= ~DAS08_DO_MASK;
+               devpriv->do_mux_bits |= DAS08_OP(s->state);
+               outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL);
+               spin_unlock(&dev->spinlock);
+       }
+
+       data[1] = s->state;
 
        return insn->n;
 }
@@ -316,17 +312,13 @@ static int das08jr_di_rbits(struct comedi_device *dev,
 
 static int das08jr_do_wbits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
-       struct das08_private_struct *devpriv = dev->private;
-
-       /*  null bits we are going to set */
-       devpriv->do_bits &= ~data[0];
-       /*  set new bit values */
-       devpriv->do_bits |= data[0] & data[1];
-       outb(devpriv->do_bits, dev->iobase + DAS08JR_DIO);
+       if (comedi_dio_update_state(s, data))
+               outb(s->state, dev->iobase + DAS08JR_DIO);
 
-       data[1] = devpriv->do_bits;
+       data[1] = s->state;
 
        return insn->n;
 }
index cce1b584200a82acbf1036af85fa91c103b2d3e8..46a314c5113e56c5699ae242b66db2e4b19c79a0 100644 (file)
@@ -41,7 +41,6 @@ struct das08_board_struct {
 
 struct das08_private_struct {
        unsigned int do_mux_bits;       /*  bits for do/mux register on boards without separate do register */
-       unsigned int do_bits;   /*  bits for do register on boards with register dedicated to digital out only */
        const unsigned int *pg_gainlist;
        unsigned int ao_readback[2];    /* assume 2 AO channels */
 };
index 1b0793f33b9f12742453d18ca5801601f87413b4..a8446ca041106b8987ea16daa9b39e09d8ed590b 100644 (file)
@@ -675,21 +675,19 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
        if (cmd->scan_begin_src == TRIG_TIMER) {
                unsigned int tmp = cmd->scan_begin_arg;
                /*  set divisors, correct timing arguments */
-               i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
-                                              &devpriv->divisor1,
-                                              &devpriv->divisor2,
-                                              &cmd->scan_begin_arg,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->clockbase,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->scan_begin_arg, cmd->flags);
                err += (tmp != cmd->scan_begin_arg);
        }
        if (cmd->convert_src == TRIG_TIMER) {
                unsigned int tmp = cmd->convert_arg;
                /*  set divisors, correct timing arguments */
-               i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
-                                              &devpriv->divisor1,
-                                              &devpriv->divisor2,
-                                              &cmd->convert_arg,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->clockbase,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                err += (tmp != cmd->convert_arg);
        }
        if (err)
@@ -725,11 +723,9 @@ static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
        struct das16_private_struct *devpriv = dev->private;
        unsigned long timer_base = dev->iobase + DAS16_TIMER_BASE_REG;
 
-       i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
-                                      &devpriv->divisor1,
-                                      &devpriv->divisor2,
-                                      &ns,
-                                      rounding_flags & TRIG_ROUND_MASK);
+       i8253_cascade_ns_to_timer(devpriv->clockbase,
+                                 &devpriv->divisor1, &devpriv->divisor2,
+                                 &ns, rounding_flags);
 
        /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
        i8254_load(timer_base, 0, 1, devpriv->divisor1, 2);
@@ -850,7 +846,7 @@ static void das16_ai_munge(struct comedi_device *dev,
                           unsigned int start_chan_index)
 {
        unsigned int i, num_samples = num_bytes / sizeof(short);
-       short *data = array;
+       unsigned short *data = array;
 
        for (i = 0; i < num_samples; i++) {
                data[i] = le16_to_cpu(data[i]);
@@ -952,15 +948,8 @@ static int das16_do_insn_bits(struct comedi_device *dev,
                              struct comedi_insn *insn,
                              unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outb(s->state, dev->iobase + DAS16_DIO_REG);
-       }
 
        data[1] = s->state;
 
@@ -1043,14 +1032,15 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                status = inb(dev->iobase + DAS1600_STATUS_REG);
 
                if (status & DAS1600_STATUS_CLK_10MHZ)
-                       devpriv->clockbase = 100;
+                       devpriv->clockbase = I8254_OSC_BASE_10MHZ;
                else
-                       devpriv->clockbase = 1000;
+                       devpriv->clockbase = I8254_OSC_BASE_1MHZ;
        } else {
                if (it->options[3])
-                       devpriv->clockbase = 1000 / it->options[3];
+                       devpriv->clockbase = I8254_OSC_BASE_1MHZ /
+                                            it->options[3];
                else
-                       devpriv->clockbase = 1000;      /*  1 MHz default */
+                       devpriv->clockbase = I8254_OSC_BASE_1MHZ;
        }
 
        /* initialize dma */
index b943c449b69198ef9782137d65c5c0a0cd5524a1..fce9acfe8084596d8c6f9b5c522c276a9ac0dd24 100644 (file)
@@ -63,8 +63,6 @@ irq can be omitted, although the cmd interface will not work without it.
 #define DAS16M1_SIZE 16
 #define DAS16M1_SIZE2 8
 
-#define DAS16M1_XTAL 100       /* 10 MHz master clock */
-
 #define FIFO_SIZE 1024         /*  1024 sample fifo */
 
 /*
@@ -133,19 +131,18 @@ struct das16m1_private_struct {
         * needed to keep track of whether new count has been loaded into
         * counter yet (loaded by first sample conversion) */
        u16 initial_hw_count;
-       short ai_buffer[FIFO_SIZE];
-       unsigned int do_bits;   /*  saves status of digital output bits */
+       unsigned short ai_buffer[FIFO_SIZE];
        unsigned int divisor1;  /*  divides master clock to obtain conversion speed */
        unsigned int divisor2;  /*  divides master clock to obtain conversion speed */
        unsigned long extra_iobase;
 };
 
-static inline short munge_sample(short data)
+static inline unsigned short munge_sample(unsigned short data)
 {
        return (data >> 4) & 0xfff;
 }
 
-static void munge_sample_array(short *array, unsigned int num_elements)
+static void munge_sample_array(unsigned short *array, unsigned int num_elements)
 {
        unsigned int i;
 
@@ -208,11 +205,10 @@ static int das16m1_cmd_test(struct comedi_device *dev,
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
                /* calculate counter values that give desired timing */
-               i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL,
-                                              &(devpriv->divisor1),
-                                              &(devpriv->divisor2),
-                                              &(cmd->convert_arg),
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (tmp != cmd->convert_arg)
                        err++;
        }
@@ -251,9 +247,10 @@ static unsigned int das16m1_set_pacer(struct comedi_device *dev,
 {
        struct das16m1_private_struct *devpriv = dev->private;
 
-       i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL, &(devpriv->divisor1),
-                                      &(devpriv->divisor2), &ns,
-                                      rounding_flags & TRIG_ROUND_MASK);
+       i8253_cascade_ns_to_timer_2div(I8254_OSC_BASE_10MHZ,
+                                      &devpriv->divisor1,
+                                      &devpriv->divisor2,
+                                      &ns, rounding_flags);
 
        /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
        i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 1, devpriv->divisor1,
@@ -393,22 +390,13 @@ static int das16m1_di_rbits(struct comedi_device *dev,
 
 static int das16m1_do_wbits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
-       struct das16m1_private_struct *devpriv = dev->private;
-       unsigned int wbits;
-
-       /*  only set bits that have been masked */
-       data[0] &= 0xf;
-       wbits = devpriv->do_bits;
-       /*  zero bits that have been masked */
-       wbits &= ~data[0];
-       /*  set masked bits */
-       wbits |= data[0] & data[1];
-       devpriv->do_bits = wbits;
-       data[1] = wbits;
+       if (comedi_dio_update_state(s, data))
+               outb(s->state, dev->iobase + DAS16M1_DIO);
 
-       outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO);
+       data[1] = s->state;
 
        return insn->n;
 }
@@ -649,7 +637,7 @@ static int das16m1_attach(struct comedi_device *dev,
        outb(TOTAL_CLEAR, dev->iobase + DAS16M1_8254_FIRST_CNTRL);
 
        /*  initialize digital output lines */
-       outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO);
+       outb(0, dev->iobase + DAS16M1_DIO);
 
        /* set the interrupt level */
        if (dev->irq)
index 5b300294d3229171d2212d962bdc626a57810f09..1880038956d05dcd6234ac7e18af4326380769f6 100644 (file)
@@ -108,7 +108,6 @@ TODO:
 /* misc. defines */
 #define DAS1800_SIZE           16      /* uses 16 io addresses */
 #define FIFO_SIZE              1024    /*  1024 sample fifo */
-#define TIMER_BASE             200     /*  5 Mhz master clock */
 #define UNIPOLAR               0x4     /*  bit that determines whether input range is uni/bipolar */
 #define DMA_BUF_SIZE           0x1ff00 /*  size in bytes of dma buffers */
 
@@ -427,7 +426,6 @@ struct das1800_private {
        volatile unsigned int count;    /* number of data points left to be taken */
        unsigned int divisor1;  /* value to load into board's counter 1 for timed conversions */
        unsigned int divisor2;  /* value to load into board's counter 2 for timed conversions */
-       int do_bits;            /* digital output bits */
        int irq_dma_bits;       /* bits for control register b */
        /* dma bits for control register b, stored so that dma can be
         * turned on and off */
@@ -440,7 +438,8 @@ struct das1800_private {
        uint16_t *dma_current_buf;      /* pointer to dma buffer currently being used */
        unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
        unsigned long iobase2;  /* secondary io address used for analog out on 'ao' boards */
-       short ao_update_bits;   /* remembers the last write to the 'update' dac */
+       unsigned short ao_update_bits;  /* remembers the last write to the
+                                        * 'update' dac */
 };
 
 /* analog out range for 'ao' boards */
@@ -503,7 +502,7 @@ static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
                                          struct comedi_subdevice *s)
 {
        struct das1800_private *devpriv = dev->private;
-       short dpnt;
+       unsigned short dpnt;
        int unipolar;
        struct comedi_cmd *cmd = &s->async->cmd;
 
@@ -840,12 +839,11 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
                if (cmd->scan_begin_src == TRIG_FOLLOW) {
                        tmp_arg = cmd->convert_arg;
                        /* calculate counter values that give desired timing */
-                       i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                                      &(devpriv->divisor1),
-                                                      &(devpriv->divisor2),
-                                                      &(cmd->convert_arg),
-                                                      cmd->
-                                                      flags & TRIG_ROUND_MASK);
+                       i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
+                                                 &devpriv->divisor1,
+                                                 &devpriv->divisor2,
+                                                 &cmd->convert_arg,
+                                                 cmd->flags);
                        if (tmp_arg != cmd->convert_arg)
                                err++;
                }
@@ -870,16 +868,11 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
                                }
                                tmp_arg = cmd->scan_begin_arg;
                                /* calculate counter values that give desired timing */
-                               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                                              &(devpriv->
-                                                                divisor1),
-                                                              &(devpriv->
-                                                                divisor2),
-                                                              &(cmd->
-                                                                scan_begin_arg),
-                                                              cmd->
-                                                              flags &
-                                                              TRIG_ROUND_MASK);
+                               i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
+                                                         &devpriv->divisor1,
+                                                         &devpriv->divisor2,
+                                                         &cmd->scan_begin_arg,
+                                                         cmd->flags);
                                if (tmp_arg != cmd->scan_begin_arg)
                                        err++;
                        }
@@ -1011,12 +1004,10 @@ static int setup_counters(struct comedi_device *dev,
                if (cmd->convert_src == TRIG_TIMER) {
                        /* set conversion frequency */
                        period = cmd->convert_arg;
-                       i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                                      &devpriv->divisor1,
-                                                      &devpriv->divisor2,
-                                                      &period,
-                                                      cmd->flags &
-                                                       TRIG_ROUND_MASK);
+                       i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
+                                                 &devpriv->divisor1,
+                                                 &devpriv->divisor2,
+                                                 &period, cmd->flags);
                        if (das1800_set_frequency(dev) < 0)
                                return -1;
                }
@@ -1024,9 +1015,10 @@ static int setup_counters(struct comedi_device *dev,
        case TRIG_TIMER:        /*  in burst mode */
                /* set scan frequency */
                period = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE, &devpriv->divisor1,
-                                              &devpriv->divisor2, &period,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &period, cmd->flags);
                if (das1800_set_frequency(dev) < 0)
                        return -1;
                break;
@@ -1220,7 +1212,7 @@ static int das1800_ai_rinsn(struct comedi_device *dev,
        int i, n;
        int chan, range, aref, chan_range;
        int timeout = 1000;
-       short dpnt;
+       unsigned short dpnt;
        int conv_flags = 0;
        unsigned long irq_flags;
 
@@ -1285,7 +1277,7 @@ static int das1800_ao_winsn(struct comedi_device *dev,
        int chan = CR_CHAN(insn->chanspec);
 /* int range = CR_RANGE(insn->chanspec); */
        int update_chan = thisboard->ao_n_chan - 1;
-       short output;
+       unsigned short output;
        unsigned long irq_flags;
 
        /*   card expects two's complement data */
@@ -1319,24 +1311,15 @@ static int das1800_di_rbits(struct comedi_device *dev,
        return insn->n;
 }
 
-/* writes to digital output channels */
 static int das1800_do_wbits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
-       struct das1800_private *devpriv = dev->private;
-       unsigned int wbits;
-
-       /*  only set bits that have been masked */
-       data[0] &= (1 << s->n_chan) - 1;
-       wbits = devpriv->do_bits;
-       wbits &= ~data[0];
-       wbits |= data[0] & data[1];
-       devpriv->do_bits = wbits;
-
-       outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
+       if (comedi_dio_update_state(s, data))
+               outb(s->state, dev->iobase + DAS1800_DIGITAL);
 
-       data[1] = devpriv->do_bits;
+       data[1] = s->state;
 
        return insn->n;
 }
@@ -1644,7 +1627,7 @@ static int das1800_attach(struct comedi_device *dev,
        das1800_cancel(dev, dev->read_subdev);
 
        /*  initialize digital out channels */
-       outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
+       outb(0, dev->iobase + DAS1800_DIGITAL);
 
        /*  initialize analog out channels */
        if (thisboard->ao_ability == 1) {
index 11e16114e4e3150ccca1763f44107ee6e2238dad..5af0a5764a8c77c728998558025c0289605d0512 100644 (file)
@@ -66,7 +66,6 @@ cmd triggers supported:
 #include "comedi_fc.h"
 
 #define DAS800_SIZE           8
-#define TIMER_BASE            1000
 #define N_CHAN_AI             8        /*  number of analog input channels */
 
 /* Registers for the das800 */
@@ -356,11 +355,10 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev,
                int tmp = cmd->convert_arg;
 
                /* calculate counter values that give desired timing */
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &devpriv->divisor1,
-                                              &devpriv->divisor2,
-                                              &cmd->convert_arg,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_1MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (tmp != cmd->convert_arg)
                        err++;
        }
@@ -630,13 +628,9 @@ static int das800_do_insn_bits(struct comedi_device *dev,
                               unsigned int *data)
 {
        struct das800_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
        unsigned long irq_flags;
 
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
+       if (comedi_dio_update_state(s, data)) {
                devpriv->do_bits = s->state << 4;
 
                spin_lock_irqsave(&dev->spinlock, irq_flags);
index 118a4fd129f903ee3481c392644e115a8ef56188..b04a5633f754ef3c286ca0ef7615ba67152482d4 100644 (file)
@@ -596,52 +596,40 @@ static int dmm32at_ao_rinsn(struct comedi_device *dev,
 
 static int dmm32at_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
        struct dmm32at_private *devpriv = dev->private;
-       unsigned char diobits;
-
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               /* Write out the new digital output lines */
-               /* outw(s->state,dev->iobase + DMM32AT_DIO); */
+       unsigned int mask;
+       unsigned int val;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               /* get access to the DIO regs */
+               outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL);
+
+               /* if either part of dio is set for output */
+               if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
+                   ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
+                       val = (s->state & 0x00ff0000) >> 16;
+                       outb(val, dev->iobase + DMM32AT_DIOC);
+               }
+               if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
+                       val = (s->state & 0x0000ff00) >> 8;
+                       outb(val, dev->iobase + DMM32AT_DIOB);
+               }
+               if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
+                       val = (s->state & 0x000000ff);
+                       outb(val, dev->iobase + DMM32AT_DIOA);
+               }
        }
 
-       /* get access to the DIO regs */
-       outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL);
-
-       /* if either part of dio is set for output */
-       if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
-           ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
-               diobits = (s->state & 0x00ff0000) >> 16;
-               outb(diobits, dev->iobase + DMM32AT_DIOC);
-       }
-       if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
-               diobits = (s->state & 0x0000ff00) >> 8;
-               outb(diobits, dev->iobase + DMM32AT_DIOB);
-       }
-       if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
-               diobits = (s->state & 0x000000ff);
-               outb(diobits, dev->iobase + DMM32AT_DIOA);
-       }
+       val = inb(dev->iobase + DMM32AT_DIOA);
+       val |= inb(dev->iobase + DMM32AT_DIOB) << 8;
+       val |= inb(dev->iobase + DMM32AT_DIOC) << 16;
+       s->state = val;
 
-       /* now read the state back in */
-       s->state = inb(dev->iobase + DMM32AT_DIOC);
-       s->state <<= 8;
-       s->state |= inb(dev->iobase + DMM32AT_DIOB);
-       s->state <<= 8;
-       s->state |= inb(dev->iobase + DMM32AT_DIOA);
-       data[1] = s->state;
-
-       /* on return, data[1] contains the value of the digital
-        * input and output lines. */
-       /* data[1]=inw(dev->iobase + DMM32AT_DIO); */
-       /* or we could just return the software copy of the output values if
-        * it was a purely digital output subdevice */
-       /* data[1]=s->state; */
+       data[1] = val;
 
        return insn->n;
 }
index 38918a1198aa83cfbcc717f69be05c074b9bd7aa..811c8c59c01761f87ef8a9936cd3b648d8ea3751 100644 (file)
@@ -260,7 +260,8 @@ static int dt2801_readdata(struct comedi_device *dev, int *data)
 
 static int dt2801_readdata2(struct comedi_device *dev, int *data)
 {
-       int lb, hb;
+       int lb = 0;
+       int hb = 0;
        int ret;
 
        ret = dt2801_readdata(dev, &lb);
@@ -528,23 +529,23 @@ static int dt2801_ao_insn_write(struct comedi_device *dev,
 
 static int dt2801_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       int which = 0;
-
-       if (s == &dev->subdevices[3])
-               which = 1;
+       int which = (s == &dev->subdevices[3]) ? 1 : 0;
+       unsigned int val = 0;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                dt2801_writecmd(dev, DT_C_WRITE_DIG);
                dt2801_writedata(dev, which);
                dt2801_writedata(dev, s->state);
        }
+
        dt2801_writecmd(dev, DT_C_READ_DIG);
        dt2801_writedata(dev, which);
-       dt2801_readdata(dev, data + 1);
+       dt2801_readdata(dev, &val);
+
+       data[1] = val;
 
        return insn->n;
 }
index a41a5716f3584fdbb488203b1c87b055fe5ae84f..0ca02fa7ba1b96e1a92edd97a81ca92a623bc711 100644 (file)
@@ -353,11 +353,11 @@ static int dt2811_di_insn_bits(struct comedi_device *dev,
 
 static int dt2811_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       s->state &= ~data[0];
-       s->state |= data[0] & data[1];
-       outb(s->state, dev->iobase + DT2811_DIO);
+       if (comedi_dio_update_state(s, data))
+               outb(s->state, dev->iobase + DT2811_DIO);
 
        data[1] = s->state;
 
index f4a8529239b5448b5fe5c9a317b0dfaf1146bc46..bf589936e5465f7822d47cc7e31c4d2162fa5fa9 100644 (file)
@@ -80,36 +80,31 @@ static int dt2817_dio_insn_config(struct comedi_device *dev,
 
 static int dt2817_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       unsigned int changed;
-
-       /* It's questionable whether it is more important in
-        * a driver like this to be deterministic or fast.
-        * We choose fast. */
-
-       if (data[0]) {
-               changed = s->state;
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-               changed ^= s->state;
-               changed &= s->io_bits;
-               if (changed & 0x000000ff)
-                       outb(s->state & 0xff, dev->iobase + DT2817_DATA + 0);
-               if (changed & 0x0000ff00)
-                       outb((s->state >> 8) & 0xff,
-                            dev->iobase + DT2817_DATA + 1);
-               if (changed & 0x00ff0000)
-                       outb((s->state >> 16) & 0xff,
-                            dev->iobase + DT2817_DATA + 2);
-               if (changed & 0xff000000)
-                       outb((s->state >> 24) & 0xff,
-                            dev->iobase + DT2817_DATA + 3);
+       unsigned long iobase = dev->iobase + DT2817_DATA;
+       unsigned int mask;
+       unsigned int val;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               if (mask & 0x000000ff)
+                       outb(s->state & 0xff, iobase + 0);
+               if (mask & 0x0000ff00)
+                       outb((s->state >> 8) & 0xff, iobase + 1);
+               if (mask & 0x00ff0000)
+                       outb((s->state >> 16) & 0xff, iobase + 2);
+               if (mask & 0xff000000)
+                       outb((s->state >> 24) & 0xff, iobase + 3);
        }
-       data[1] = inb(dev->iobase + DT2817_DATA + 0);
-       data[1] |= (inb(dev->iobase + DT2817_DATA + 1) << 8);
-       data[1] |= (inb(dev->iobase + DT2817_DATA + 2) << 16);
-       data[1] |= (inb(dev->iobase + DT2817_DATA + 3) << 24);
+
+       val = inb(iobase + 0);
+       val |= (inb(iobase + 1) << 8);
+       val |= (inb(iobase + 2) << 16);
+       val |= (inb(iobase + 3) << 24);
+
+       data[1] = val;
 
        return insn->n;
 }
index da3ee859bdbcedd025708fa0af0ac434df241b26..a01e6b553887ab23480d8de187ef0079a662715e 100644 (file)
@@ -226,7 +226,7 @@ struct dt282x_private {
 
        const struct comedi_lrange *darangelist[2];
 
-       short ao[2];
+       unsigned short ao[2];
 
        volatile int dacsr;     /* software copies of registers */
        volatile int adcsr;
@@ -237,7 +237,7 @@ struct dt282x_private {
 
        struct {
                int chan;
-               short *buf;     /* DMA buffer */
+               unsigned short *buf;    /* DMA buffer */
                volatile int size;      /* size of current transfer */
        } dma[2];
        int dma_maxsize;        /* max size of DMA transfer (in bytes) */
@@ -283,7 +283,7 @@ static void dt282x_disable_dma(struct comedi_device *dev);
 
 static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2);
 
-static void dt282x_munge(struct comedi_device *dev, short *buf,
+static void dt282x_munge(struct comedi_device *dev, unsigned short *buf,
                         unsigned int nbytes)
 {
        const struct dt282x_board *board = comedi_board(dev);
@@ -496,9 +496,9 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
 #if 0
        if (adcsr & DT2821_ADDONE) {
                int ret;
-               short data;
+               unsigned short data;
 
-               data = (short)inw(dev->iobase + DT2821_ADDAT);
+               data = inw(dev->iobase + DT2821_ADDAT);
                data &= (1 << board->adbits) - 1;
 
                if (devpriv->ad_2scomp)
@@ -796,7 +796,7 @@ static int dt282x_ao_insn_write(struct comedi_device *dev,
 {
        const struct dt282x_board *board = comedi_board(dev);
        struct dt282x_private *devpriv = dev->private;
-       short d;
+       unsigned short d;
        unsigned int chan;
 
        chan = CR_CHAN(insn->chanspec);
@@ -967,14 +967,12 @@ static int dt282x_ao_cancel(struct comedi_device *dev,
 
 static int dt282x_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + DT2821_DIODAT);
-       }
+
        data[1] = inw(dev->iobase + DT2821_DIODAT);
 
        return insn->n;
index 64ef87598b607deffe7b9a11999c753defbce126..292226eeff924dd6c7b9dccda948d6bbce476016 100644 (file)
@@ -331,7 +331,7 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev,
        int rear;
        int count;
        int i;
-       short data;
+       unsigned short data;
 
        front = readw(devpriv->io_addr + DPR_AD_Buf_Front);
        count = front - devpriv->ai_front;
@@ -665,13 +665,12 @@ static int dt3k_dio_insn_config(struct comedi_device *dev,
 
 static int dt3k_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[1] & data[0];
+       if (comedi_dio_update_state(s, data))
                dt3k_writesingle(dev, SUBS_DOUT, 0, s->state);
-       }
+
        data[1] = dt3k_readsingle(dev, SUBS_DIN, 0, 0);
 
        return insn->n;
index b5e6f33dc217c4493f595ddedc82e86a3b5b2ee1..73af600c172532d05ac634b83c094fa983a20a49 100644 (file)
@@ -85,13 +85,9 @@ for my needs.
 #define F020_MASK_DACxCN_DACxEN                0x80
 
 enum {
-       /* A/D  D/A  DI  DO  CT */
-       DT9812_DEVID_DT9812_10, /*  8    2   8   8   1  +/- 10V */
-       DT9812_DEVID_DT9812_2PT5,       /* 8    2   8   8   1  0-2.44V */
-#if 0
-       DT9812_DEVID_DT9813,    /*  16   2   4   4   1  +/- 10V */
-       DT9812_DEVID_DT9814     /*  24   2   0   0   1  +/- 10V */
-#endif
+                                       /* A/D  D/A  DI  DO  CT */
+       DT9812_DEVID_DT9812_10,         /*  8    2   8   8   1  +/- 10V */
+       DT9812_DEVID_DT9812_2PT5,       /*  8    2   8   8   1  0-2.44V */
 };
 
 enum dt9812_gain {
@@ -580,15 +576,8 @@ static int dt9812_do_insn_bits(struct comedi_device *dev,
                               struct comedi_insn *insn,
                               unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                dt9812_digital_out(dev, s->state);
-       }
 
        data[1] = s->state;
 
index fd525f499f2a2db47d16eef9a9f07b780cc00690..f2a9f1c2f3b6dfe2ffa563a53c466ac7bd7fd987 100644 (file)
@@ -147,33 +147,23 @@ static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
-/* digital output bit interface */
 static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev,
-                             struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                                    struct comedi_subdevice *s,
+                                    struct comedi_insn *insn,
+                                    unsigned int *data)
 {
        struct dyna_pci10xx_private *devpriv = dev->private;
 
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit.
-        * s->state contains the previous write data
-        */
        mutex_lock(&devpriv->mutex);
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                smp_mb();
                outw_p(s->state, devpriv->BADR3);
                udelay(10);
        }
 
-       /*
-        * On return, data[1] contains the value of the digital
-        * input and output lines. We just return the software copy of the
-        * output values if it was a purely digital output subdevice.
-        */
        data[1] = s->state;
        mutex_unlock(&devpriv->mutex);
+
        return insn->n;
 }
 
index 8d70f64b157478b43c79eb32ad2952962e7316e3..e3ff4c43897978ef7caf355215358bf2595e3a12 100644 (file)
@@ -25,8 +25,7 @@ Configuration options:
 
 #define FL512_SIZE 16          /* the size of the used memory */
 struct fl512_private {
-
-       short ao_readback[2];
+       unsigned short ao_readback[2];
 };
 
 static const struct comedi_lrange range_fl512 = { 4, {
index 3889d23292d04d322dcba5d37dbf6d14c0a8aab0..1e16641ec52d6991bce167d633a03f475f73a936 100644 (file)
@@ -118,9 +118,7 @@ struct icp_multi_private {
        unsigned char act_chanlist_len; /*  len of scanlist */
        unsigned char act_chanlist_pos; /*  actual position in MUX list */
        unsigned int *ai_chanlist;      /*  actaul chanlist */
-       short *ai_data;         /*  data buffer */
-       short ao_data[4];       /*  data output buffer */
-       short di_data;          /*  Digital input data */
+       unsigned short ao_data[4];      /*  data output buffer */
        unsigned int do_data;   /*  Remember digital output data */
 };
 
@@ -348,18 +346,13 @@ static int icp_multi_insn_bits_di(struct comedi_device *dev,
 
 static int icp_multi_insn_bits_do(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        struct icp_multi_private *devpriv = dev->private;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-
-               printk(KERN_DEBUG "Digital outputs = %4x \n", s->state);
-
+       if (comedi_dio_update_state(s, data))
                writew(s->state, devpriv->io_addr + ICP_MULTI_DO);
-       }
 
        data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
 
@@ -548,7 +541,6 @@ static int icp_multi_auto_attach(struct comedi_device *dev,
        s->maxdata = 1;
        s->len_chanlist = 16;
        s->range_table = &range_digital;
-       s->io_bits = 0;
        s->insn_bits = icp_multi_insn_bits_di;
 
        s = &dev->subdevices[3];
@@ -558,8 +550,6 @@ static int icp_multi_auto_attach(struct comedi_device *dev,
        s->maxdata = 1;
        s->len_chanlist = 8;
        s->range_table = &range_digital;
-       s->io_bits = 0xff;
-       s->state = 0;
        s->insn_bits = icp_multi_insn_bits_do;
 
        s = &dev->subdevices[4];
index 5c3a318b464012bff1f5a44c2788e20008399ed7..8577778441fa8cfa1f5af64f40f82e4cc7d0ee15 100644 (file)
@@ -378,13 +378,10 @@ static int ii20k_dio_insn_bits(struct comedi_device *dev,
                               unsigned int *data)
 {
        struct ii20k_private *devpriv = dev->private;
-       unsigned int mask = data[0] & s->io_bits;       /* outputs only */
-       unsigned int bits = data[1];
+       unsigned int mask;
 
+       mask = comedi_dio_update_state(s, data);
        if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
                if (mask & 0x000000ff)
                        writeb((s->state >> 0) & 0xff,
                               devpriv->ioaddr + II20K_DIO0_REG);
index 8f4afadab76a617a526da821d3ac029562eadf3c..3d12e913592649f3eb4c1dc999058695f27b8a86 100644 (file)
@@ -427,7 +427,7 @@ static int xilinx_download(struct comedi_device *dev)
 static void me4000_reset(struct comedi_device *dev)
 {
        struct me4000_info *info = dev->private;
-       unsigned long val;
+       unsigned int val;
        int chan;
 
        /* Make a hardware reset */
@@ -480,9 +480,9 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
        int rang = CR_RANGE(insn->chanspec);
        int aref = CR_AREF(insn->chanspec);
 
-       unsigned long entry = 0;
-       unsigned long tmp;
-       long lval;
+       unsigned int entry = 0;
+       unsigned int tmp;
+       unsigned int lval;
 
        if (insn->n == 0) {
                return 0;
@@ -586,7 +586,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
 static int me4000_ai_cancel(struct comedi_device *dev,
                            struct comedi_subdevice *s)
 {
-       unsigned long tmp;
+       unsigned int tmp;
 
        /* Stop any running conversion */
        tmp = inl(dev->iobase + ME4000_AI_CTRL_REG);
@@ -783,7 +783,7 @@ static int ai_prepare(struct comedi_device *dev,
                      unsigned int scan_ticks, unsigned int chan_ticks)
 {
 
-       unsigned long tmp = 0;
+       unsigned int tmp = 0;
 
        /* Write timer arguments */
        ai_write_timer(dev, init_ticks, scan_ticks, chan_ticks);
@@ -1108,7 +1108,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
        struct comedi_subdevice *s = &dev->subdevices[0];
        int i;
        int c = 0;
-       long lval;
+       unsigned int lval;
 
        if (!dev->attached)
                return IRQ_NONE;
@@ -1252,7 +1252,7 @@ static int me4000_ao_insn_write(struct comedi_device *dev,
        int chan = CR_CHAN(insn->chanspec);
        int rang = CR_RANGE(insn->chanspec);
        int aref = CR_AREF(insn->chanspec);
-       unsigned long tmp;
+       unsigned int tmp;
 
        if (insn->n == 0) {
                return 0;
@@ -1313,29 +1313,12 @@ static int me4000_ao_insn_read(struct comedi_device *dev,
        return 1;
 }
 
-/*=============================================================================
-  Digital I/O section
-  ===========================================================================*/
-
 static int me4000_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       /*
-        * The insn data consists of a mask in data[0] and the new data
-        * in data[1]. The mask defines which bits we are concerning about.
-        * The new data must be anded with the mask.
-        * Each channel corresponds to a bit.
-        */
-       if (data[0]) {
-               /* Check if requested ports are configured for output */
-               if ((s->io_bits & data[0]) != data[0])
-                       return -EIO;
-
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-
-               /* Write out the new digital output lines */
+       if (comedi_dio_update_state(s, data)) {
                outl((s->state >> 0) & 0xFF,
                            dev->iobase + ME4000_DIO_PORT_0_REG);
                outl((s->state >> 8) & 0xFF,
@@ -1346,8 +1329,6 @@ static int me4000_dio_insn_bits(struct comedi_device *dev,
                            dev->iobase + ME4000_DIO_PORT_3_REG);
        }
 
-       /* On return, data[1] contains the value of
-          the digital input and output lines. */
        data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) |
                  ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) |
                  ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) |
index a6f6d4a46587f06d1b84ba53a45df3ebcf150821..24ec9ef9b1a0fc326ac560aa74a5b57105fd2647 100644 (file)
@@ -222,15 +222,11 @@ static int me_dio_insn_bits(struct comedi_device *dev,
        struct me_private_data *dev_private = dev->private;
        void __iomem *mmio_porta = dev_private->me_regbase + ME_DIO_PORT_A;
        void __iomem *mmio_portb = dev_private->me_regbase + ME_DIO_PORT_B;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
+       unsigned int mask;
        unsigned int val;
 
-       mask &= s->io_bits;     /* only update the COMEDI_OUTPUT channels */
+       mask = comedi_dio_update_state(s, data);
        if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
                if (mask & 0x0000ffff)
                        writew((s->state & 0xffff), mmio_porta);
                if (mask & 0xffff0000)
@@ -545,7 +541,6 @@ static int me_auto_attach(struct comedi_device *dev,
        s->range_table  = &range_digital;
        s->insn_bits    = me_dio_insn_bits;
        s->insn_config  = me_dio_insn_config;
-       s->io_bits      = 0;
 
        dev_info(dev->class_dev, "%s: %s attached\n",
                dev->driver->driver_name, dev->board_name);
index 9d75ea4e201bcb553cc5cb75b38b759d0fe87e65..3ca755eca285dd129741640c7153f7a0413dcfe8 100644 (file)
@@ -163,11 +163,11 @@ static int multiq3_di_insn_bits(struct comedi_device *dev,
 
 static int multiq3_do_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       s->state &= ~data[0];
-       s->state |= (data[0] & data[1]);
-       outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT);
+       if (comedi_dio_update_state(s, data))
+               outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT);
 
        data[1] = s->state;
 
index c2745f201f2c19cb713b812630c0d0774fb3c5d8..85aa9609d6a280994bffaa8ad72f0eac5c3c3861 100644 (file)
@@ -1,41 +1,33 @@
 /*
-    comedi/drivers/ni_6527.c
-    driver for National Instruments PCI-6527
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
-
-    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.
-*/
-/*
-Driver: ni_6527
-Description: National Instruments 6527
-Author: ds
-Status: works
-Devices: [National Instruments] PCI-6527 (ni6527), PXI-6527
-Updated: Sat, 25 Jan 2003 13:24:40 -0800
-
-
-*/
+ * ni_6527.c
+ * Comedi driver for National Instruments PCI-6527
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
 
 /*
-   Manuals (available from ftp://ftp.natinst.com/support/manuals)
-
-       370106b.pdf     6527 Register Level Programmer Manual
-
+ * Driver: ni_6527
+ * Description: National Instruments 6527
+ * Devices: (National Instruments) PCI-6527 [pci-6527]
+ *          (National Instruments) PXI-6527 [pxi-6527]
+ * Author: David A. Schleef <ds@schleef.org>
+ * Updated: Sat, 25 Jan 2003 13:24:40 -0800
+ * Status: works
+ *
+ * Configuration Options: not applicable, uses PCI auto config
  */
 
-#define DEBUG 1
-#define DEBUG_FLAGS
-
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
@@ -43,39 +35,41 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800
 #include "../comedidev.h"
 
 #include "comedi_fc.h"
-#include "mite.h"
-
-#define DRIVER_NAME "ni_6527"
-
-#define NI6527_DIO_SIZE 4096
-#define NI6527_MITE_SIZE 4096
-
-#define Port_Register(x)                       (0x00+(x))
-#define ID_Register                            0x06
-
-#define Clear_Register                         0x07
-#define ClrEdge                                0x08
-#define ClrOverflow                    0x04
-#define ClrFilter                      0x02
-#define ClrInterval                    0x01
 
-#define Filter_Interval(x)                     (0x08+(x))
-#define Filter_Enable(x)                       (0x0c+(x))
-
-#define Change_Status                          0x14
-#define MasterInterruptStatus          0x04
-#define Overflow                       0x02
-#define EdgeStatus                     0x01
-
-#define Master_Interrupt_Control               0x15
-#define FallingEdgeIntEnable           0x10
-#define RisingEdgeIntEnable            0x08
-#define MasterInterruptEnable          0x04
-#define OverflowIntEnable              0x02
-#define EdgeIntEnable                  0x01
-
-#define Rising_Edge_Detection_Enable(x)                (0x018+(x))
-#define Falling_Edge_Detection_Enable(x)       (0x020+(x))
+/*
+ * PCI BAR1 - Register memory map
+ *
+ * Manuals (available from ftp://ftp.natinst.com/support/manuals)
+ *     370106b.pdf     6527 Register Level Programmer Manual
+ */
+#define NI6527_DI_REG(x)               (0x00 + (x))
+#define NI6527_DO_REG(x)               (0x03 + (x))
+#define NI6527_ID_REG                  0x06
+#define NI6527_CLR_REG                 0x07
+#define NI6527_CLR_EDGE                        (1 << 3)
+#define NI6527_CLR_OVERFLOW            (1 << 2)
+#define NI6527_CLR_FILT                        (1 << 1)
+#define NI6527_CLR_INTERVAL            (1 << 0)
+#define NI6527_CLR_IRQS                        (NI6527_CLR_EDGE | NI6527_CLR_OVERFLOW)
+#define NI6527_CLR_RESET_FILT          (NI6527_CLR_FILT | NI6527_CLR_INTERVAL)
+#define NI6527_FILT_INTERVAL_REG(x)    (0x08 + (x))
+#define NI6527_FILT_ENA_REG(x)         (0x0c + (x))
+#define NI6527_STATUS_REG              0x14
+#define NI6527_STATUS_IRQ              (1 << 2)
+#define NI6527_STATUS_OVERFLOW         (1 << 1)
+#define NI6527_STATUS_EDGE             (1 << 0)
+#define NI6527_CTRL_REG                        0x15
+#define NI6527_CTRL_FALLING            (1 << 4)
+#define NI6527_CTRL_RISING             (1 << 3)
+#define NI6527_CTRL_IRQ                        (1 << 2)
+#define NI6527_CTRL_OVERFLOW           (1 << 1)
+#define NI6527_CTRL_EDGE               (1 << 0)
+#define NI6527_CTRL_DISABLE_IRQS       0
+#define NI6527_CTRL_ENABLE_IRQS                (NI6527_CTRL_FALLING | \
+                                        NI6527_CTRL_RISING | \
+                                        NI6527_CTRL_IRQ | NI6527_CTRL_EDGE)
+#define NI6527_RISING_EDGE_REG(x)      (0x18 + (x))
+#define NI6527_FALLING_EDGE_REG(x)     (0x20 + (x))
 
 enum ni6527_boardid {
        BOARD_PCI6527,
@@ -96,96 +90,113 @@ static const struct ni6527_board ni6527_boards[] = {
 };
 
 struct ni6527_private {
-       struct mite_struct *mite;
+       void __iomem *mmio_base;
        unsigned int filter_interval;
        unsigned int filter_enable;
 };
 
+static void ni6527_set_filter_interval(struct comedi_device *dev,
+                                      unsigned int val)
+{
+       struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+
+       if (val != devpriv->filter_interval) {
+               writeb(val & 0xff, mmio + NI6527_FILT_INTERVAL_REG(0));
+               writeb((val >> 8) & 0xff, mmio + NI6527_FILT_INTERVAL_REG(1));
+               writeb((val >> 16) & 0x0f, mmio + NI6527_FILT_INTERVAL_REG(2));
+
+               writeb(NI6527_CLR_INTERVAL, mmio + NI6527_CLR_REG);
+
+               devpriv->filter_interval = val;
+       }
+}
+
+static void ni6527_set_filter_enable(struct comedi_device *dev,
+                                    unsigned int val)
+{
+       struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+
+       writeb(val & 0xff, mmio + NI6527_FILT_ENA_REG(0));
+       writeb((val >> 8) & 0xff, mmio + NI6527_FILT_ENA_REG(1));
+       writeb((val >> 16) & 0xff, mmio + NI6527_FILT_ENA_REG(2));
+}
+
 static int ni6527_di_insn_config(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
        struct ni6527_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
+       unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned int interval;
 
-       if (insn->n != 2)
-               return -EINVAL;
-
-       if (data[0] != INSN_CONFIG_FILTER)
-               return -EINVAL;
-
-       if (data[1]) {
+       switch (data[0]) {
+       case INSN_CONFIG_FILTER:
+               /*
+                * The deglitch filter interval is specified in nanoseconds.
+                * The hardware supports intervals in 200ns increments. Round
+                * the user values up and return the actual interval.
+                */
                interval = (data[1] + 100) / 200;
                data[1] = interval * 200;
 
-               if (interval != devpriv->filter_interval) {
-                       writeb(interval & 0xff,
-                              devpriv->mite->daq_io_addr + Filter_Interval(0));
-                       writeb((interval >> 8) & 0xff,
-                              devpriv->mite->daq_io_addr + Filter_Interval(1));
-                       writeb((interval >> 16) & 0x0f,
-                              devpriv->mite->daq_io_addr + Filter_Interval(2));
-
-                       writeb(ClrInterval,
-                              devpriv->mite->daq_io_addr + Clear_Register);
-
-                       devpriv->filter_interval = interval;
+               if (interval) {
+                       ni6527_set_filter_interval(dev, interval);
+                       devpriv->filter_enable |= 1 << chan;
+               } else {
+                       devpriv->filter_enable &= ~(1 << chan);
                }
-
-               devpriv->filter_enable |= 1 << chan;
-       } else {
-               devpriv->filter_enable &= ~(1 << chan);
+               ni6527_set_filter_enable(dev, devpriv->filter_enable);
+               break;
+       default:
+               return -EINVAL;
        }
 
-       writeb(devpriv->filter_enable,
-              devpriv->mite->daq_io_addr + Filter_Enable(0));
-       writeb(devpriv->filter_enable >> 8,
-              devpriv->mite->daq_io_addr + Filter_Enable(1));
-       writeb(devpriv->filter_enable >> 16,
-              devpriv->mite->daq_io_addr + Filter_Enable(2));
-
-       return 2;
+       return insn->n;
 }
 
 static int ni6527_di_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+       unsigned int val;
 
-       data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0));
-       data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8;
-       data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16;
+       val = readb(mmio + NI6527_DI_REG(0));
+       val |= (readb(mmio + NI6527_DI_REG(1)) << 8);
+       val |= (readb(mmio + NI6527_DI_REG(2)) << 16);
+
+       data[1] = val;
 
        return insn->n;
 }
 
 static int ni6527_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct ni6527_private *devpriv = dev->private;
-
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-
-               /* The open relay state on the board cooresponds to 1,
-                * but in Comedi, it is represented by 0. */
-               if (data[0] & 0x0000ff) {
-                       writeb((s->state ^ 0xff),
-                              devpriv->mite->daq_io_addr + Port_Register(3));
-               }
-               if (data[0] & 0x00ff00) {
-                       writeb((s->state >> 8) ^ 0xff,
-                              devpriv->mite->daq_io_addr + Port_Register(4));
-               }
-               if (data[0] & 0xff0000) {
-                       writeb((s->state >> 16) ^ 0xff,
-                              devpriv->mite->daq_io_addr + Port_Register(5));
-               }
+       void __iomem *mmio = devpriv->mmio_base;
+       unsigned int mask;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               /* Outputs are inverted */
+               unsigned int val = s->state ^ 0xffffff;
+
+               if (mask & 0x0000ff)
+                       writeb(val & 0xff, mmio + NI6527_DO_REG(0));
+               if (mask & 0x00ff00)
+                       writeb((val >> 8) & 0xff, mmio + NI6527_DO_REG(1));
+               if (mask & 0xff0000)
+                       writeb((val >> 16) & 0xff, mmio + NI6527_DO_REG(2));
        }
+
        data[1] = s->state;
 
        return insn->n;
@@ -195,21 +206,22 @@ static irqreturn_t ni6527_interrupt(int irq, void *d)
 {
        struct comedi_device *dev = d;
        struct ni6527_private *devpriv = dev->private;
-       struct comedi_subdevice *s = &dev->subdevices[2];
+       struct comedi_subdevice *s = dev->read_subdev;
+       void __iomem *mmio = devpriv->mmio_base;
        unsigned int status;
 
-       status = readb(devpriv->mite->daq_io_addr + Change_Status);
-       if ((status & MasterInterruptStatus) == 0)
-               return IRQ_NONE;
-       if ((status & EdgeStatus) == 0)
+       status = readb(mmio + NI6527_STATUS_REG);
+       if (!(status & NI6527_STATUS_IRQ))
                return IRQ_NONE;
 
-       writeb(ClrEdge | ClrOverflow,
-              devpriv->mite->daq_io_addr + Clear_Register);
+       if (status & NI6527_STATUS_EDGE) {
+               comedi_buf_put(s->async, 0);
+               s->async->events |= COMEDI_CB_EOS;
+               comedi_event(dev, s);
+       }
+
+       writeb(NI6527_CLR_IRQS, mmio + NI6527_CLR_REG);
 
-       comedi_buf_put(s->async, 0);
-       s->async->events |= COMEDI_CB_EOS;
-       comedi_event(dev, s);
        return IRQ_HANDLED;
 }
 
@@ -259,13 +271,10 @@ static int ni6527_intr_cmd(struct comedi_device *dev,
                           struct comedi_subdevice *s)
 {
        struct ni6527_private *devpriv = dev->private;
-       /* struct comedi_cmd *cmd = &s->async->cmd; */
+       void __iomem *mmio = devpriv->mmio_base;
 
-       writeb(ClrEdge | ClrOverflow,
-              devpriv->mite->daq_io_addr + Clear_Register);
-       writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
-              MasterInterruptEnable | EdgeIntEnable,
-              devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+       writeb(NI6527_CLR_IRQS, mmio + NI6527_CLR_REG);
+       writeb(NI6527_CTRL_ENABLE_IRQS, mmio + NI6527_CTRL_REG);
 
        return 0;
 }
@@ -274,8 +283,9 @@ static int ni6527_intr_cancel(struct comedi_device *dev,
                              struct comedi_subdevice *s)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
 
-       writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+       writeb(NI6527_CTRL_DISABLE_IRQS, mmio + NI6527_CTRL_REG);
 
        return 0;
 }
@@ -288,32 +298,54 @@ static int ni6527_intr_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
+static void ni6527_set_edge_detection(struct comedi_device *dev,
+                                     unsigned int rising,
+                                     unsigned int falling)
+{
+       struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
+
+       /* enable rising-edge detection channels */
+       writeb(rising & 0xff, mmio + NI6527_RISING_EDGE_REG(0));
+       writeb((rising >> 8) & 0xff, mmio + NI6527_RISING_EDGE_REG(1));
+       writeb((rising >> 16) & 0xff, mmio + NI6527_RISING_EDGE_REG(2));
+
+       /* enable falling-edge detection channels */
+       writeb(falling & 0xff, mmio + NI6527_FALLING_EDGE_REG(0));
+       writeb((falling >> 8) & 0xff, mmio + NI6527_FALLING_EDGE_REG(1));
+       writeb((falling >> 16) & 0xff, mmio + NI6527_FALLING_EDGE_REG(2));
+}
+
 static int ni6527_intr_insn_config(struct comedi_device *dev,
                                   struct comedi_subdevice *s,
-                                  struct comedi_insn *insn, unsigned int *data)
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
+{
+       switch (data[0]) {
+       case INSN_CONFIG_CHANGE_NOTIFY:
+               /* check_insn_config_length() does not check this instruction */
+               if (insn->n != 3)
+                       return -EINVAL;
+               ni6527_set_edge_detection(dev, data[1], data[2]);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return insn->n;
+}
+
+static void ni6527_reset(struct comedi_device *dev)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *mmio = devpriv->mmio_base;
 
-       if (insn->n < 1)
-               return -EINVAL;
-       if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
-               return -EINVAL;
+       /* disable deglitch filters on all channels */
+       ni6527_set_filter_enable(dev, 0);
 
-       writeb(data[1],
-              devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
-       writeb(data[1] >> 8,
-              devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
-       writeb(data[1] >> 16,
-              devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
-
-       writeb(data[2],
-              devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
-       writeb(data[2] >> 8,
-              devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
-       writeb(data[2] >> 16,
-              devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
-
-       return 2;
+       writeb(NI6527_CLR_IRQS | NI6527_CLR_RESET_FILT,
+              mmio + NI6527_CLR_REG);
+       writeb(NI6527_CTRL_DISABLE_IRQS, mmio + NI6527_CTRL_REG);
 }
 
 static int ni6527_auto_attach(struct comedi_device *dev,
@@ -332,75 +364,69 @@ static int ni6527_auto_attach(struct comedi_device *dev,
        dev->board_ptr = board;
        dev->board_name = board->name;
 
+       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+       if (!devpriv)
+               return -ENOMEM;
+
        ret = comedi_pci_enable(dev);
        if (ret)
                return ret;
 
-       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-       if (!devpriv)
+       devpriv->mmio_base = pci_ioremap_bar(pcidev, 1);
+       if (!devpriv->mmio_base)
                return -ENOMEM;
 
-       devpriv->mite = mite_alloc(pcidev);
-       if (!devpriv->mite)
-               return -ENOMEM;
+       /* make sure this is actually a 6527 device */
+       if (readb(devpriv->mmio_base + NI6527_ID_REG) != 0x27)
+               return -ENODEV;
 
-       ret = mite_setup(devpriv->mite);
-       if (ret < 0) {
-               dev_err(dev->class_dev, "error setting up mite\n");
-               return ret;
-       }
+       ni6527_reset(dev);
 
-       dev_info(dev->class_dev, "board: %s, ID=0x%02x\n", dev->board_name,
-                readb(devpriv->mite->daq_io_addr + ID_Register));
+       ret = request_irq(pcidev->irq, ni6527_interrupt, IRQF_SHARED,
+                         dev->board_name, dev);
+       if (ret == 0)
+               dev->irq = pcidev->irq;
 
        ret = comedi_alloc_subdevices(dev, 3);
        if (ret)
                return ret;
 
+       /* Digital Input subdevice */
        s = &dev->subdevices[0];
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE;
-       s->n_chan = 24;
-       s->range_table = &range_digital;
-       s->maxdata = 1;
-       s->insn_config = ni6527_di_insn_config;
-       s->insn_bits = ni6527_di_insn_bits;
-
+       s->type         = COMEDI_SUBD_DI;
+       s->subdev_flags = SDF_READABLE;
+       s->n_chan       = 24;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_config  = ni6527_di_insn_config;
+       s->insn_bits    = ni6527_di_insn_bits;
+
+       /* Digital Output subdevice */
        s = &dev->subdevices[1];
-       s->type = COMEDI_SUBD_DO;
-       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-       s->n_chan = 24;
-       s->range_table = &range_unknown;  /* FIXME: actually conductance */
-       s->maxdata = 1;
-       s->insn_bits = ni6527_do_insn_bits;
-
+       s->type         = COMEDI_SUBD_DO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = 24;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = ni6527_do_insn_bits;
+
+       /* Edge detection interrupt subdevice */
        s = &dev->subdevices[2];
-       dev->read_subdev = s;
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
-       s->n_chan = 1;
-       s->range_table = &range_unknown;
-       s->maxdata = 1;
-       s->do_cmdtest = ni6527_intr_cmdtest;
-       s->do_cmd = ni6527_intr_cmd;
-       s->cancel = ni6527_intr_cancel;
-       s->insn_bits = ni6527_intr_insn_bits;
-       s->insn_config = ni6527_intr_insn_config;
-
-       writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0));
-       writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(1));
-       writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(2));
-
-       writeb(ClrEdge | ClrOverflow | ClrFilter | ClrInterval,
-              devpriv->mite->daq_io_addr + Clear_Register);
-       writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
-
-       ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
-                         IRQF_SHARED, DRIVER_NAME, dev);
-       if (ret < 0)
-               dev_warn(dev->class_dev, "irq not available\n");
-       else
-               dev->irq = mite_irq(devpriv->mite);
+       if (dev->irq) {
+               dev->read_subdev = s;
+               s->type         = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+               s->n_chan       = 1;
+               s->maxdata      = 1;
+               s->range_table  = &range_digital;
+               s->insn_config  = ni6527_intr_insn_config;
+               s->insn_bits    = ni6527_intr_insn_bits;
+               s->do_cmdtest   = ni6527_intr_cmdtest;
+               s->do_cmd       = ni6527_intr_cmd;
+               s->cancel       = ni6527_intr_cancel;
+       } else {
+               s->type = COMEDI_SUBD_UNUSED;
+       }
 
        return 0;
 }
@@ -409,23 +435,18 @@ static void ni6527_detach(struct comedi_device *dev)
 {
        struct ni6527_private *devpriv = dev->private;
 
-       if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr)
-               writeb(0x00,
-                      devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+       if (devpriv && devpriv->mmio_base)
+               ni6527_reset(dev);
        if (dev->irq)
                free_irq(dev->irq, dev);
-       if (devpriv && devpriv->mite) {
-               mite_unsetup(devpriv->mite);
-               mite_free(devpriv->mite);
-       }
        comedi_pci_disable(dev);
 }
 
 static struct comedi_driver ni6527_driver = {
-       .driver_name = DRIVER_NAME,
-       .module = THIS_MODULE,
-       .auto_attach = ni6527_auto_attach,
-       .detach = ni6527_detach,
+       .driver_name    = "ni_6527",
+       .module         = THIS_MODULE,
+       .auto_attach    = ni6527_auto_attach,
+       .detach         = ni6527_detach,
 };
 
 static int ni6527_pci_probe(struct pci_dev *dev,
@@ -442,7 +463,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
 MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
 
 static struct pci_driver ni6527_pci_driver = {
-       .name           = DRIVER_NAME,
+       .name           = "ni_6527",
        .id_table       = ni6527_pci_table,
        .probe          = ni6527_pci_probe,
        .remove         = comedi_pci_auto_unconfig,
@@ -450,5 +471,5 @@ static struct pci_driver ni6527_pci_driver = {
 module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for National Instruments PCI-6527");
 MODULE_LICENSE("GPL");
index 3607336dafe297968395871e00bd0a14fa700bd5..8a991dcab24a9b5a08cdcaf480979292337db555 100644 (file)
@@ -1213,7 +1213,6 @@ static int ni_660x_auto_attach(struct comedi_device *dev,
        s->range_table = &range_digital;
        s->insn_bits = ni_660x_dio_insn_bits;
        s->insn_config = ni_660x_dio_insn_config;
-       s->io_bits = 0;         /* all bits default to input */
        /*  we use the ioconfig registers to control dio direction, so zero
        output enables in stc dio control reg */
        ni_660x_write_register(dev, 0, 0, STCDIOControl);
index e2926ce3fb24be9799e1ce2fe949992dfacc17c3..e4414cf110e7e3a72e049d48d0c00c32a7e7d6c6 100644 (file)
@@ -136,20 +136,15 @@ static int ni_670x_ao_rinsn(struct comedi_device *dev,
 
 static int ni_670x_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
        struct ni_670x_private *devpriv = dev->private;
        void __iomem *io_addr = devpriv->mite->daq_io_addr +
                                        DIO_PORT0_DATA_OFFSET;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                writel(s->state, io_addr);
-       }
 
        data[1] = readl(io_addr);
 
index 2512ce8dfcaa7bd2a830fc29aaf307555b115d28..63c847932eb88983fbe082c969cfb94787293e95 100644 (file)
@@ -154,7 +154,7 @@ struct a2150_private {
 
        volatile unsigned int count;    /* number of data points left to be taken */
        unsigned int dma;       /*  dma channel */
-       s16 *dma_buffer;        /*  dma buffer */
+       uint16_t *dma_buffer;   /*  dma buffer */
        unsigned int dma_transfer_size; /*  size in bytes of dma transfers */
        int irq_dma_bits;       /*  irq/dma register bits */
        int config_bits;        /*  config register bits */
@@ -192,7 +192,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d)
        struct comedi_async *async;
        struct comedi_cmd *cmd;
        unsigned int max_points, num_points, residue, leftover;
-       short dpnt;
+       unsigned short dpnt;
        static const int sample_size = sizeof(devpriv->dma_buffer[0]);
 
        if (!dev->attached) {
@@ -684,13 +684,12 @@ static int a2150_set_chanlist(struct comedi_device *dev,
                devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
                break;
        case 2:
-               if (start_channel == 0) {
+               if (start_channel == 0)
                        devpriv->config_bits |= CHANNEL_BITS(0x2);
-               } else if (start_channel == 2) {
+               else if (start_channel == 2)
                        devpriv->config_bits |= CHANNEL_BITS(0x3);
-               } else {
+               else
                        return -1;
-               }
                break;
        case 4:
                devpriv->config_bits |= CHANNEL_BITS(0x1);
index b9122fd835e1e714cec811c43d2c6c1a51675e9e..10e3e9475ee2c544336ea3075755df30972240e1 100644 (file)
 /*
-    comedi/drivers/ni_at_ao.c
-    Driver for NI AT-AO-6/10 boards
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 2000,2002 David A. Schleef <ds@schleef.org>
-
-    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.
-*/
-/*
-Driver: ni_at_ao
-Description: National Instruments AT-AO-6/10
-Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10)
-Status: should work
-Author: ds
-Updated: Sun Dec 26 12:26:28 EST 2004
-
-Configuration options:
-  [0] - I/O port base address
-  [1] - IRQ (unused)
-  [2] - DMA (unused)
-  [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V
-       bipolar, 1 for 0V to 10V unipolar)
-
-*/
+ * ni_at_ao.c
+ * Driver for NI AT-AO-6/10 boards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000,2002 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
+
 /*
- * Register-level programming information can be found in NI
- * document 320379.pdf.
+ * Driver: ni_at_ao
+ * Description: National Instruments AT-AO-6/10
+ * Devices: (National Instruments) AT-AO-6 [at-ao-6]
+ *          (National Instruments) AT-AO-10 [at-ao-10]
+ * Status: should work
+ * Author: David A. Schleef <ds@schleef.org>
+ * Updated: Sun Dec 26 12:26:28 EST 2004
+ *
+ * Configuration options:
+ *   [0] - I/O port base address
+ *   [1] - IRQ (unused)
+ *   [2] - DMA (unused)
+ *   [3] - analog output range, set by jumpers on hardware
+ *         0 for -10 to 10V bipolar
+ *         1 for 0V to 10V unipolar
  */
 
 #include <linux/module.h>
-#include "../comedidev.h"
 
-/* board egisters */
-/* registers with _2_ are accessed when GRP2WR is set in CFG1 */
+#include "../comedidev.h"
 
-#define ATAO_SIZE 0x20
-
-#define ATAO_2_DMATCCLR                0x00    /* W 16 */
-#define ATAO_DIN               0x00    /* R 16 */
-#define ATAO_DOUT              0x00    /* W 16 */
-
-#define ATAO_CFG2              0x02    /* W 16 */
-#define CALLD1 0x8000
-#define CALLD0 0x4000
-#define FFRTEN 0x2000
-#define DAC2S8 0x1000
-#define DAC2S6 0x0800
-#define DAC2S4 0x0400
-#define DAC2S2 0x0200
-#define DAC2S0 0x0100
-#define LDAC8          0x0080
-#define LDAC6          0x0040
-#define LDAC4          0x0020
-#define LDAC2          0x0010
-#define LDAC0          0x0008
-#define PROMEN 0x0004
-#define SCLK           0x0002
-#define SDATA          0x0001
-
-#define ATAO_2_INT1CLR         0x02    /* W 16 */
-
-#define ATAO_CFG3              0x04    /* W 16 */
-#define DMAMODE        0x0040
-#define CLKOUT 0x0020
-#define RCLKEN 0x0010
-#define DOUTEN2        0x0008
-#define DOUTEN1        0x0004
-#define EN2_5V 0x0002
-#define SCANEN 0x0001
-
-#define ATAO_2_INT2CLR         0x04    /* W 16 */
-
-#define ATAO_82C53_BASE                0x06    /* RW 8 */
-
-#define ATAO_82C53_CNTR1       0x06    /* RW 8 */
-#define ATAO_82C53_CNTR2       0x07    /* RW 8 */
-#define ATAO_82C53_CNTR3       0x08    /* RW 8 */
-#define ATAO_82C53_CNTRCMD     0x09    /* W 8 */
-#define CNTRSEL1       0x80
-#define CNTRSEL0       0x40
-#define RWSEL1 0x20
-#define RWSEL0 0x10
-#define MODESEL2       0x08
-#define MODESEL1       0x04
-#define MODESEL0       0x02
-#define BCDSEL 0x01
-  /* read-back command */
-#define COUNT          0x20
-#define STATUS 0x10
-#define CNTR3          0x08
-#define CNTR2          0x04
-#define CNTR1          0x02
-  /* status */
-#define OUT            0x80
-#define _NULL          0x40
-#define RW1            0x20
-#define RW0            0x10
-#define MODE2          0x08
-#define MODE1          0x04
-#define MODE0          0x02
-#define BCD            0x01
-
-#define ATAO_2_RTSISHFT                0x06    /* W 8 */
-#define RSI            0x01
-
-#define ATAO_2_RTSISTRB                0x07    /* W 8 */
-
-#define ATAO_CFG1              0x0a    /* W 16 */
-#define EXTINT2EN      0x8000
-#define EXTINT1EN      0x4000
-#define CNTINT2EN      0x2000
-#define CNTINT1EN      0x1000
-#define TCINTEN        0x0800
-#define CNT1SRC        0x0400
-#define CNT2SRC        0x0200
-#define FIFOEN 0x0100
-#define GRP2WR 0x0080
-#define EXTUPDEN       0x0040
-#define DMARQ          0x0020
-#define DMAEN          0x0010
-#define CH_mask        0x000f
-#define ATAO_STATUS            0x0a    /* R 16 */
-#define FH             0x0040
-#define FE             0x0020
-#define FF             0x0010
-#define INT2           0x0008
-#define INT1           0x0004
-#define TCINT          0x0002
-#define PROMOUT        0x0001
-
-#define ATAO_FIFO_WRITE                0x0c    /* W 16 */
-#define ATAO_FIFO_CLEAR                0x0c    /* R 16 */
-#define ATAO_DACn(x)           (0x0c + 2*(x))  /* W */
+#include "8253.h"
 
 /*
- * Board descriptions for two imaginary boards.  Describing the
- * boards in this way is optional, and completely driver-dependent.
- * Some drivers use arrays such as this, other do not.
+ * Register map
+ *
+ * Register-level programming information can be found in NI
+ * document 320379.pdf.
  */
+#define ATAO_DIO_REG           0x00
+#define ATAO_CFG2_REG          0x02
+#define ATAO_CFG2_CALLD_NOP    (0 << 14)
+#define ATAO_CFG2_CALLD(x)     ((((x) >> 3) + 1) << 14)
+#define ATAO_CFG2_FFRTEN       (1 << 13)
+#define ATAO_CFG2_DACS(x)      (1 << (((x) / 2) + 8))
+#define ATAO_CFG2_LDAC(x)      (1 << (((x) / 2) + 3))
+#define ATAO_CFG2_PROMEN       (1 << 2)
+#define ATAO_CFG2_SCLK         (1 << 1)
+#define ATAO_CFG2_SDATA                (1 << 0)
+#define ATAO_CFG3_REG          0x04
+#define ATAO_CFG3_DMAMODE      (1 << 6)
+#define ATAO_CFG3_CLKOUT       (1 << 5)
+#define ATAO_CFG3_RCLKEN       (1 << 4)
+#define ATAO_CFG3_DOUTEN2      (1 << 3)
+#define ATAO_CFG3_DOUTEN1      (1 << 2)
+#define ATAO_CFG3_EN2_5V       (1 << 1)
+#define ATAO_CFG3_SCANEN       (1 << 0)
+#define ATAO_82C53_BASE                0x06
+#define ATAO_CFG1_REG          0x0a
+#define ATAO_CFG1_EXTINT2EN    (1 << 15)
+#define ATAO_CFG1_EXTINT1EN    (1 << 14)
+#define ATAO_CFG1_CNTINT2EN    (1 << 13)
+#define ATAO_CFG1_CNTINT1EN    (1 << 12)
+#define ATAO_CFG1_TCINTEN      (1 << 11)
+#define ATAO_CFG1_CNT1SRC      (1 << 10)
+#define ATAO_CFG1_CNT2SRC      (1 << 9)
+#define ATAO_CFG1_FIFOEN       (1 << 8)
+#define ATAO_CFG1_GRP2WR       (1 << 7)
+#define ATAO_CFG1_EXTUPDEN     (1 << 6)
+#define ATAO_CFG1_DMARQ                (1 << 5)
+#define ATAO_CFG1_DMAEN                (1 << 4)
+#define ATAO_CFG1_CH(x)                (((x) & 0xf) << 0)
+#define ATAO_STATUS_REG                0x0a
+#define ATAO_STATUS_FH         (1 << 6)
+#define ATAO_STATUS_FE         (1 << 5)
+#define ATAO_STATUS_FF         (1 << 4)
+#define ATAO_STATUS_INT2       (1 << 3)
+#define ATAO_STATUS_INT1       (1 << 2)
+#define ATAO_STATUS_TCINT      (1 << 1)
+#define ATAO_STATUS_PROMOUT    (1 << 0)
+#define ATAO_FIFO_WRITE_REG    0x0c
+#define ATAO_FIFO_CLEAR_REG    0x0c
+#define ATAO_AO_REG(x)         (0x0c + ((x) * 2))
+
+/* registers with _2_ are accessed when GRP2WR is set in CFG1 */
+#define ATAO_2_DMATCCLR_REG    0x00
+#define ATAO_2_INT1CLR_REG     0x02
+#define ATAO_2_INT2CLR_REG     0x04
+#define ATAO_2_RTSISHFT_REG    0x06
+#define ATAO_2_RTSISHFT_RSI    (1 << 0)
+#define ATAO_2_RTSISTRB_REG    0x07
+
 struct atao_board {
        const char *name;
        int n_ao_chans;
 };
 
-struct atao_private {
+static const struct atao_board atao_boards[] = {
+       {
+               .name           = "at-ao-6",
+               .n_ao_chans     = 6,
+       }, {
+               .name           = "at-ao-10",
+               .n_ao_chans     = 10,
+       },
+};
 
+struct atao_private {
        unsigned short cfg1;
-       unsigned short cfg2;
        unsigned short cfg3;
 
        /* Used for AO readback */
        unsigned int ao_readback[10];
+
+       /* Used for caldac readback */
+       unsigned char caldac[21];
 };
 
-static void atao_reset(struct comedi_device *dev)
+static void atao_select_reg_group(struct comedi_device *dev, int group)
 {
        struct atao_private *devpriv = dev->private;
 
-       /* This is the reset sequence described in the manual */
-
-       devpriv->cfg1 = 0;
-       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-
-       outb(RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
-       outb(0x03, dev->iobase + ATAO_82C53_CNTR1);
-       outb(CNTRSEL0 | RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
-
-       devpriv->cfg2 = 0;
-       outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
-
-       devpriv->cfg3 = 0;
-       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
-
-       inw(dev->iobase + ATAO_FIFO_CLEAR);
-
-       devpriv->cfg1 |= GRP2WR;
-       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-
-       outw(0, dev->iobase + ATAO_2_INT1CLR);
-       outw(0, dev->iobase + ATAO_2_INT2CLR);
-       outw(0, dev->iobase + ATAO_2_DMATCCLR);
-
-       devpriv->cfg1 &= ~GRP2WR;
-       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+       if (group)
+               devpriv->cfg1 |= ATAO_CFG1_GRP2WR;
+       else
+               devpriv->cfg1 &= ~ATAO_CFG1_GRP2WR;
+       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
 }
 
-static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-                        struct comedi_insn *insn, unsigned int *data)
+static int atao_ao_insn_write(struct comedi_device *dev,
+                             struct comedi_subdevice *s,
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
        struct atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int val;
        int i;
-       int chan = CR_CHAN(insn->chanspec);
-       short bits;
+
+       if (chan == 0)
+               atao_select_reg_group(dev, 1);
 
        for (i = 0; i < insn->n; i++) {
-               bits = data[i] - 0x800;
-               if (chan == 0) {
-                       devpriv->cfg1 |= GRP2WR;
-                       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-               }
-               outw(bits, dev->iobase + ATAO_DACn(chan));
-               if (chan == 0) {
-                       devpriv->cfg1 &= ~GRP2WR;
-                       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
-               }
-               devpriv->ao_readback[chan] = data[i];
+               val = data[i];
+               devpriv->ao_readback[chan] = val;
+
+               /* munge offset binary (unsigned) to two's complement */
+               val = comedi_offset_munge(s, val);
+               outw(val, dev->iobase + ATAO_AO_REG(chan));
        }
 
-       return i;
+       if (chan == 0)
+               atao_select_reg_group(dev, 0);
+
+       return insn->n;
 }
 
-static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-                        struct comedi_insn *insn, unsigned int *data)
+static int atao_ao_insn_read(struct comedi_device *dev,
+                            struct comedi_subdevice *s,
+                            struct comedi_insn *insn,
+                            unsigned int *data)
 {
        struct atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
        int i;
-       int chan = CR_CHAN(insn->chanspec);
 
        for (i = 0; i < insn->n; i++)
                data[i] = devpriv->ao_readback[chan];
 
-       return i;
+       return insn->n;
 }
 
 static int atao_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               outw(s->state, dev->iobase + ATAO_DOUT);
-       }
+       if (comedi_dio_update_state(s, data))
+               outw(s->state, dev->iobase + ATAO_DIO_REG);
 
-       data[1] = inw(dev->iobase + ATAO_DIN);
+       data[1] = inw(dev->iobase + ATAO_DIO_REG);
 
        return insn->n;
 }
@@ -266,57 +212,128 @@ static int atao_dio_insn_config(struct comedi_device *dev,
                return ret;
 
        if (s->io_bits & 0x0f)
-               devpriv->cfg3 |= DOUTEN1;
+               devpriv->cfg3 |= ATAO_CFG3_DOUTEN1;
        else
-               devpriv->cfg3 &= ~DOUTEN1;
+               devpriv->cfg3 &= ~ATAO_CFG3_DOUTEN1;
        if (s->io_bits & 0xf0)
-               devpriv->cfg3 |= DOUTEN2;
+               devpriv->cfg3 |= ATAO_CFG3_DOUTEN2;
        else
-               devpriv->cfg3 &= ~DOUTEN2;
+               devpriv->cfg3 &= ~ATAO_CFG3_DOUTEN2;
 
-       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
+       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3_REG);
 
        return insn->n;
 }
 
 /*
- * Figure 2-1 in the manual shows 3 chips labeled DAC8800, which
- * are 8-channel 8-bit DACs.  These are most likely the calibration
- * DACs.  It is not explicitly stated in the manual how to access
- * the caldacs, but we can guess.
+ * There are three DAC8800 TrimDACs on the board. These are 8-channel,
+ * 8-bit DACs that are used to calibrate the Analog Output channels.
+ * The factory default calibration values are stored in the EEPROM.
+ * The TrimDACs, and EEPROM addresses, are mapped as:
+ *
+ *        Channel       EEPROM  Description
+ *   -----------------  ------  -----------------------------------
+ *    0 - DAC0 Chan 0    0x30   AO Channel 0 Offset
+ *    1 - DAC0 Chan 1    0x31   AO Channel 0 Gain
+ *    2 - DAC0 Chan 2    0x32   AO Channel 1 Offset
+ *    3 - DAC0 Chan 3    0x33   AO Channel 1 Gain
+ *    4 - DAC0 Chan 4    0x34   AO Channel 2 Offset
+ *    5 - DAC0 Chan 5    0x35   AO Channel 2 Gain
+ *    6 - DAC0 Chan 6    0x36   AO Channel 3 Offset
+ *    7 - DAC0 Chan 7    0x37   AO Channel 3 Gain
+ *    8 - DAC1 Chan 0    0x38   AO Channel 4 Offset
+ *    9 - DAC1 Chan 1    0x39   AO Channel 4 Gain
+ *   10 - DAC1 Chan 2    0x3a   AO Channel 5 Offset
+ *   11 - DAC1 Chan 3    0x3b   AO Channel 5 Gain
+ *   12 - DAC1 Chan 4    0x3c   2.5V Offset
+ *   13 - DAC1 Chan 5    0x3d   AO Channel 6 Offset (at-ao-10 only)
+ *   14 - DAC1 Chan 6    0x3e   AO Channel 6 Gain   (at-ao-10 only)
+ *   15 - DAC1 Chan 7    0x3f   AO Channel 7 Offset (at-ao-10 only)
+ *   16 - DAC2 Chan 0    0x40   AO Channel 7 Gain   (at-ao-10 only)
+ *   17 - DAC2 Chan 1    0x41   AO Channel 8 Offset (at-ao-10 only)
+ *   18 - DAC2 Chan 2    0x42   AO Channel 8 Gain   (at-ao-10 only)
+ *   19 - DAC2 Chan 3    0x43   AO Channel 9 Offset (at-ao-10 only)
+ *   20 - DAC2 Chan 4    0x44   AO Channel 9 Gain   (at-ao-10 only)
+ *        DAC2 Chan 5    0x45   Reserved
+ *        DAC2 Chan 6    0x46   Reserved
+ *        DAC2 Chan 7    0x47   Reserved
  */
+static int atao_calib_insn_write(struct comedi_device *dev,
+                                struct comedi_subdevice *s,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
+{
+       struct atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int bitstring;
+       unsigned int val;
+       int bit;
+
+       if (insn->n == 0)
+               return 0;
+
+       devpriv->caldac[chan] = data[insn->n - 1] & s->maxdata;
+
+       /* write the channel and last data value to the caldac */
+       bitstring = ((chan & 0x7) << 8) | devpriv->caldac[chan];
+
+       /* clock the bitstring to the caldac; MSB -> LSB */
+       for (bit = 1 << 10; bit; bit >>= 1) {
+               val = (bit & bitstring) ? ATAO_CFG2_SDATA : 0;
+
+               outw(val, dev->iobase + ATAO_CFG2_REG);
+               outw(val | ATAO_CFG2_SCLK, dev->iobase + ATAO_CFG2_REG);
+       }
+
+       /* strobe the caldac to load the value */
+       outw(ATAO_CFG2_CALLD(chan), dev->iobase + ATAO_CFG2_REG);
+       outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
+
+       return insn->n;
+}
+
 static int atao_calib_insn_read(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
+       struct atao_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
        int i;
+
        for (i = 0; i < insn->n; i++)
-               data[i] = 0;    /* XXX */
+               data[i] = devpriv->caldac[chan];
+
        return insn->n;
 }
 
-static int atao_calib_insn_write(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+static void atao_reset(struct comedi_device *dev)
 {
        struct atao_private *devpriv = dev->private;
-       unsigned int bitstring, bit;
-       unsigned int chan = CR_CHAN(insn->chanspec);
 
-       bitstring = ((chan & 0x7) << 8) | (data[insn->n - 1] & 0xff);
+       /* This is the reset sequence described in the manual */
 
-       for (bit = 1 << (11 - 1); bit; bit >>= 1) {
-               outw(devpriv->cfg2 | ((bit & bitstring) ? SDATA : 0),
-                    dev->iobase + ATAO_CFG2);
-               outw(devpriv->cfg2 | SCLK | ((bit & bitstring) ? SDATA : 0),
-                    dev->iobase + ATAO_CFG2);
-       }
-       /* strobe the appropriate caldac */
-       outw(devpriv->cfg2 | (((chan >> 3) + 1) << 14),
-            dev->iobase + ATAO_CFG2);
-       outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
+       devpriv->cfg1 = 0;
+       outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
 
-       return insn->n;
+       /* Put outputs of counter 1 and counter 2 in a high state */
+       i8254_load(dev->iobase + ATAO_82C53_BASE, 0,
+                  0, 0x0003, I8254_MODE4 | I8254_BINARY);
+       i8254_set_mode(dev->iobase + ATAO_82C53_BASE, 0,
+                  1, I8254_MODE4 | I8254_BINARY);
+
+       outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
+
+       devpriv->cfg3 = 0;
+       outw(devpriv->cfg3, dev->iobase + ATAO_CFG3_REG);
+
+       inw(dev->iobase + ATAO_FIFO_CLEAR_REG);
+
+       atao_select_reg_group(dev, 1);
+       outw(0, dev->iobase + ATAO_2_INT1CLR_REG);
+       outw(0, dev->iobase + ATAO_2_INT2CLR_REG);
+       outw(0, dev->iobase + ATAO_2_DMATCCLR_REG);
+       atao_select_reg_group(dev, 0);
 }
 
 static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
@@ -324,12 +341,9 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        const struct atao_board *board = comedi_board(dev);
        struct atao_private *devpriv;
        struct comedi_subdevice *s;
-       int ao_unipolar;
        int ret;
 
-       ao_unipolar = it->options[3];
-
-       ret = comedi_request_region(dev, it->options[0], ATAO_SIZE);
+       ret = comedi_request_region(dev, it->options[0], 0x20);
        if (ret)
                return ret;
 
@@ -341,60 +355,44 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        if (ret)
                return ret;
 
+       /* Analog Output subdevice */
        s = &dev->subdevices[0];
-       /* analog output subdevice */
-       s->type = COMEDI_SUBD_AO;
-       s->subdev_flags = SDF_WRITABLE;
-       s->n_chan = board->n_ao_chans;
-       s->maxdata = (1 << 12) - 1;
-       if (ao_unipolar)
-               s->range_table = &range_unipolar10;
-       else
-               s->range_table = &range_bipolar10;
-       s->insn_write = &atao_ao_winsn;
-       s->insn_read = &atao_ao_rinsn;
-
+       s->type         = COMEDI_SUBD_AO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = board->n_ao_chans;
+       s->maxdata      = 0x0fff;
+       s->range_table  = it->options[3] ? &range_unipolar10 : &range_bipolar10;
+       s->insn_write   = atao_ao_insn_write;
+       s->insn_read    = atao_ao_insn_read;
+
+       /* Digital I/O subdevice */
        s = &dev->subdevices[1];
-       /* digital i/o subdevice */
-       s->type = COMEDI_SUBD_DIO;
-       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-       s->n_chan = 8;
-       s->maxdata = 1;
-       s->range_table = &range_digital;
-       s->insn_bits = atao_dio_insn_bits;
-       s->insn_config = atao_dio_insn_config;
+       s->type         = COMEDI_SUBD_DIO;
+       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+       s->n_chan       = 8;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = atao_dio_insn_bits;
+       s->insn_config  = atao_dio_insn_config;
 
-       s = &dev->subdevices[2];
        /* caldac subdevice */
-       s->type = COMEDI_SUBD_CALIB;
-       s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
-       s->n_chan = 21;
-       s->maxdata = 0xff;
-       s->insn_read = atao_calib_insn_read;
-       s->insn_write = atao_calib_insn_write;
-
+       s = &dev->subdevices[2];
+       s->type         = COMEDI_SUBD_CALIB;
+       s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
+       s->n_chan       = (board->n_ao_chans * 2) + 1;
+       s->maxdata      = 0xff;
+       s->insn_read    = atao_calib_insn_read;
+       s->insn_write   = atao_calib_insn_write;
+
+       /* EEPROM subdevice */
        s = &dev->subdevices[3];
-       /* eeprom subdevice */
-       /* s->type=COMEDI_SUBD_EEPROM; */
-       s->type = COMEDI_SUBD_UNUSED;
+       s->type         = COMEDI_SUBD_UNUSED;
 
        atao_reset(dev);
 
-       printk(KERN_INFO "\n");
-
        return 0;
 }
 
-static const struct atao_board atao_boards[] = {
-       {
-               .name           = "ai-ao-6",
-               .n_ao_chans     = 6,
-       }, {
-               .name           = "ai-ao-10",
-               .n_ao_chans     = 10,
-       },
-};
-
 static struct comedi_driver ni_at_ao_driver = {
        .driver_name    = "ni_at_ao",
        .module         = THIS_MODULE,
@@ -407,5 +405,5 @@ static struct comedi_driver ni_at_ao_driver = {
 module_comedi_driver(ni_at_ao_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for NI AT-AO-6/10 boards");
 MODULE_LICENSE("GPL");
index bb3491f5ad21c993c916ab827cfe74dffa05ad41..a9f7d40d6db24ed32f8efcd07bef5e4ce94160f6 100644 (file)
@@ -558,13 +558,12 @@ static int atmio16d_ao_insn_write(struct comedi_device *dev,
 
 static int atmio16d_dio_insn_bits(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] | data[1]);
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + MIO_16_DIG_OUT_REG);
-       }
+
        data[1] = inw(dev->iobase + MIO_16_DIG_IN_REG);
 
        return insn->n;
index 404f83de276da21bd00cb4d17c7b87eb9fd9743d..e4cdca349157f89ab12ccf543c849769c9785dfd 100644 (file)
@@ -72,18 +72,22 @@ Manuals:    Register level: http://www.ni.com/pdf/manuals/340698.pdf
 
 static int daq700_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       unsigned int mask;
+       unsigned int val;
 
-               if (data[0] & 0xff)
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               if (mask & 0xff)
                        outb(s->state & 0xff, dev->iobase + DIO_W);
        }
 
-       data[1] = s->state & 0xff;
-       data[1] |= inb(dev->iobase + DIO_R) << 8;
+       val = s->state & 0xff;
+       val |= inb(dev->iobase + DIO_R) << 8;
+
+       data[1] = val;
 
        return insn->n;
 }
@@ -212,7 +216,6 @@ static int daq700_auto_attach(struct comedi_device *dev,
        s->maxdata      = 1;
        s->insn_bits    = daq700_dio_insn_bits;
        s->insn_config  = daq700_dio_insn_config;
-       s->state        = 0;
        s->io_bits      = 0x00ff;
 
        /* DAQCard-700 ai */
index 1add114dc0bc9d5b490d169a88e69c63f86106e6..0512445df08eb0d601bbb9f49a0f959aa2033bf5 100644 (file)
@@ -73,7 +73,6 @@
 #include "ni_labpc_isadma.h"
 
 #define LABPC_SIZE             0x20    /* size of ISA io region */
-#define LABPC_TIMER_BASE       500     /* 2 MHz master clock */
 #define LABPC_ADC_TIMEOUT      1000
 
 enum scan_mode {
@@ -201,12 +200,6 @@ static int labpc_counter_set_mode(struct comedi_device *dev,
                return i8254_set_mode(base_address, 0, counter_number, mode);
 }
 
-static bool labpc_range_is_unipolar(struct comedi_subdevice *s,
-                                   unsigned int range)
-{
-       return s->range_table->range[range].min >= 0;
-}
-
 static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        struct labpc_private *devpriv = dev->private;
@@ -272,7 +265,7 @@ static void labpc_setup_cmd6_reg(struct comedi_device *dev,
                devpriv->cmd6 &= ~CMD6_NRSE;
 
        /* bipolar or unipolar range? */
-       if (labpc_range_is_unipolar(s, range))
+       if (comedi_range_is_unipolar(s, range))
                devpriv->cmd6 |= CMD6_ADCUNI;
        else
                devpriv->cmd6 &= ~CMD6_ADCUNI;
@@ -465,13 +458,13 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
                 * clock speed on convert and scan counters)
                 */
                devpriv->divisor_b0 = (scan_period - 1) /
-                   (LABPC_TIMER_BASE * max_counter_value) + 1;
+                   (I8254_OSC_BASE_2MHZ * max_counter_value) + 1;
                if (devpriv->divisor_b0 < min_counter_value)
                        devpriv->divisor_b0 = min_counter_value;
                if (devpriv->divisor_b0 > max_counter_value)
                        devpriv->divisor_b0 = max_counter_value;
 
-               base_period = LABPC_TIMER_BASE * devpriv->divisor_b0;
+               base_period = I8254_OSC_BASE_2MHZ * devpriv->divisor_b0;
 
                /*  set a0 for conversion frequency and b1 for scan frequency */
                switch (cmd->flags & TRIG_ROUND_MASK) {
@@ -516,22 +509,20 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
                 * calculate cascaded counter values
                 * that give desired scan timing
                 */
-               i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
-                                              &(devpriv->divisor_b1),
-                                              &(devpriv->divisor_b0),
-                                              &scan_period,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
+                                         &devpriv->divisor_b1,
+                                         &devpriv->divisor_b0,
+                                         &scan_period, cmd->flags);
                labpc_set_ai_scan_period(cmd, mode, scan_period);
        } else if (convert_period) {
                /*
                 * calculate cascaded counter values
                 * that give desired conversion timing
                 */
-               i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
-                                              &(devpriv->divisor_a0),
-                                              &(devpriv->divisor_b0),
-                                              &convert_period,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
+                                         &devpriv->divisor_a0,
+                                         &devpriv->divisor_b0,
+                                         &convert_period, cmd->flags);
                labpc_set_ai_convert_period(cmd, mode, convert_period);
        }
 }
@@ -902,7 +893,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 static int labpc_drain_fifo(struct comedi_device *dev)
 {
        struct labpc_private *devpriv = dev->private;
-       short data;
+       unsigned short data;
        struct comedi_async *async = dev->read_subdev->async;
        const int timeout = 10000;
        unsigned int i;
@@ -1046,7 +1037,7 @@ static int labpc_ao_insn_write(struct comedi_device *dev,
        /* set range */
        if (board->is_labpc1200) {
                range = CR_RANGE(insn->chanspec);
-               if (labpc_range_is_unipolar(s, range))
+               if (comedi_range_is_unipolar(s, range))
                        devpriv->cmd6 |= CMD6_DACUNI(channel);
                else
                        devpriv->cmd6 &= ~CMD6_DACUNI(channel);
index 4e02770e834bd7df20e8f015c92750ba4efb05a1..5113397bfecf4c864a48aeca9ccd7cd7f718b60c 100644 (file)
@@ -1292,7 +1292,7 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
        struct comedi_cmd *cmd = &async->cmd;
        int chan;
        int i;
-       short d;
+       unsigned short d;
        u32 packed_data;
        int range;
        int err = 1;
@@ -1403,7 +1403,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
        int i;
 
        if (board->reg_type == ni_reg_611x) {
-               short data[2];
+               unsigned short data[2];
                u32 dl;
 
                for (i = 0; i < n / 2; i++) {
@@ -1420,7 +1420,7 @@ static void ni_ai_fifo_read(struct comedi_device *dev,
                        cfc_write_to_buffer(s, data[0]);
                }
        } else if (board->reg_type == ni_reg_6143) {
-               short data[2];
+               unsigned short data[2];
                u32 dl;
 
                /*  This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed */
@@ -1511,9 +1511,9 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
        const struct ni_board_struct *board = comedi_board(dev);
        struct ni_private *devpriv = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
-       short data[2];
+       unsigned short data[2];
        u32 dl;
-       short fifo_empty;
+       unsigned short fifo_empty;
        int i;
 
        if (board->reg_type == ni_reg_611x) {
@@ -1577,7 +1577,7 @@ static void get_last_sample_611x(struct comedi_device *dev)
        const struct ni_board_struct *board = comedi_board(dev);
        struct ni_private *devpriv __maybe_unused = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
-       short data;
+       unsigned short data;
        u32 dl;
 
        if (board->reg_type != ni_reg_611x)
@@ -1596,7 +1596,7 @@ static void get_last_sample_6143(struct comedi_device *dev)
        const struct ni_board_struct *board = comedi_board(dev);
        struct ni_private *devpriv __maybe_unused = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV];
-       short data;
+       unsigned short data;
        u32 dl;
 
        if (board->reg_type != ni_reg_6143)
@@ -1621,7 +1621,7 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
        struct comedi_async *async = s->async;
        unsigned int i;
        unsigned int length = num_bytes / bytes_per_sample(s);
-       short *array = data;
+       unsigned short *array = data;
        unsigned int *larray = data;
 
        for (i = 0; i < length; i++) {
@@ -2873,7 +2873,7 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
        unsigned int i;
        unsigned int offset;
        unsigned int length = num_bytes / sizeof(short);
-       short *array = data;
+       unsigned short *array = data;
 
        offset = 1 << (board->aobits - 1);
        for (i = 0; i < length; i++) {
@@ -3547,28 +3547,22 @@ static int ni_dio_insn_config(struct comedi_device *dev,
 
 static int ni_dio_insn_bits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
        struct ni_private *devpriv = dev->private;
 
-#ifdef DEBUG_DIO
-       printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]);
-#endif
-
-       if (data[0]) {
-               /* Perform check to make sure we're not using the
-                  serial part of the dio */
-               if ((data[0] & (DIO_SDIN | DIO_SDOUT))
-                   && devpriv->serial_interval_ns)
-                       return -EBUSY;
+       /* Make sure we're not using the serial part of the dio */
+       if ((data[0] & (DIO_SDIN | DIO_SDOUT)) && devpriv->serial_interval_ns)
+               return -EBUSY;
 
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data)) {
                devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
                devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
                devpriv->stc_writew(dev, devpriv->dio_output,
                                    DIO_Output_Register);
        }
+
        data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
 
        return insn->n;
@@ -3598,16 +3592,9 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
 {
        struct ni_private *devpriv __maybe_unused = dev->private;
 
-#ifdef DEBUG_DIO
-       printk("ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0],
-              data[1]);
-#endif
-
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data))
                ni_writel(s->state, M_Offset_Static_Digital_Output);
-       }
+
        data[1] = ni_readl(M_Offset_Static_Digital_Input);
 
        return insn->n;
@@ -5355,20 +5342,20 @@ static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel,
 
 static int ni_pfi_insn_bits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
        const struct ni_board_struct *board = comedi_board(dev);
        struct ni_private *devpriv __maybe_unused = dev->private;
 
-       if ((board->reg_type & ni_reg_m_series_mask) == 0) {
+       if (!(board->reg_type & ni_reg_m_series_mask))
                return -ENOTSUPP;
-       }
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+
+       if (comedi_dio_update_state(s, data))
                ni_writew(s->state, M_Offset_PFI_DO);
-       }
+
        data[1] = ni_readw(M_Offset_PFI_DI);
+
        return insn->n;
 }
 
index fad81bc97b6e090d87b1391349bf4c8ad3a4dcd9..e3a8fa96d9b398fa13c8e8f564967393d20e1d5c 100644 (file)
@@ -406,9 +406,9 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
        struct mite_struct *mite = devpriv->mite;
 
        /* int i, j; */
-       long int AuxData = 0;
-       short data1 = 0;
-       short data2 = 0;
+       unsigned int auxdata = 0;
+       unsigned short data1 = 0;
+       unsigned short data2 = 0;
        int flags;
        int status;
        int work = 0;
@@ -481,11 +481,11 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
                                              );
                                        goto out;
                                }
-                               AuxData =
+                               auxdata =
                                    readl(devpriv->mite->daq_io_addr +
                                          Group_1_FIFO);
-                               data1 = AuxData & 0xffff;
-                               data2 = (AuxData & 0xffff0000) >> 16;
+                               data1 = auxdata & 0xffff;
+                               data2 = (auxdata & 0xffff0000) >> 16;
                                comedi_buf_put(async, data1);
                                comedi_buf_put(async, data2);
                                /* DPRINTK("read:%d, %d\n",data1,data2); */
@@ -657,15 +657,14 @@ static int ni_pcidio_insn_config(struct comedi_device *dev,
 
 static int ni_pcidio_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct nidio96_private *devpriv = dev->private;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_update_state(s, data))
                writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
-       }
+
        data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
 
        return insn->n;
index 11bf0aab82ea98528f26d436e4a4c6bf4472ec4e..f0630b7897b507171cb56d1ea09f7645521ca5e4 100644 (file)
@@ -1491,7 +1491,7 @@ struct ni_board_struct {
        unsigned short pwm_up_count;    \
        unsigned short pwm_down_count;  \
        \
-       short ai_fifo_buffer[0x2000];                           \
+       unsigned short ai_fifo_buffer[0x2000];                  \
        uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; \
        uint32_t serial_number; \
        \
index e859f85a8e17c1b39ac7300f7ded90f250da1d22..f0fc123ef56603994e8338e67884283388cc80e4 100644 (file)
 /*
  comedi/drivers/pcl711.c
-   hardware driver for PC-LabCard PCL-711 and AdSys ACL-8112
-   and compatibles
-
-   COMEDI - Linux Control and Measurement Device Interface
-   Copyright (C) 1998 David A. Schleef <ds@schleef.org>
-   Janne Jalkanen <jalkanen@cs.hut.fi>
  Eric Bunn <ebu@cs.hut.fi>
-
  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.
pcl711.c
+ * Comedi driver for PC-LabCard PCL-711 and AdSys ACL-8112 and compatibles
+ * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ *                   Janne Jalkanen <jalkanen@cs.hut.fi>
+ *                   Eric Bunn <ebu@cs.hut.fi>
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ *
* 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.
  */
-/*
-Driver: pcl711
-Description: Advantech PCL-711 and 711b, ADLink ACL-8112
-Author: ds, Janne Jalkanen <jalkanen@cs.hut.fi>, Eric Bunn <ebu@cs.hut.fi>
-Status: mostly complete
-Devices: [Advantech] PCL-711 (pcl711), PCL-711B (pcl711b),
-  [AdLink] ACL-8112HG (acl8112hg), ACL-8112DG (acl8112dg)
-
-Since these boards do not have DMA or FIFOs, only immediate mode is
-supported.
-
-*/
 
 /*
-   Dave Andruczyk <dave@tech.buffalostate.edu> also wrote a
-   driver for the PCL-711.  I used a few ideas from his driver
-   here.  His driver also has more comments, if you are
-   interested in understanding how this driver works.
-   http://tech.buffalostate.edu/~dave/driver/
-
-   The ACL-8112 driver was hacked from the sources of the PCL-711
-   driver (the 744 chip used on the 8112 is almost the same as
-   the 711b chip, but it has more I/O channels) by
-   Janne Jalkanen (jalkanen@cs.hut.fi) and
-   Erik Bunn (ebu@cs.hut.fi).  Remerged with the PCL-711 driver
-   by ds.
-
-   [acl-8112]
-   This driver supports both TRIGNOW and TRIGCLK,
-   but does not yet support DMA transfers.  It also supports
-   both high (HG) and low (DG) versions of the card, though
-   the HG version has been untested.
-
+ * Driver: pcl711
+ * Description: Advantech PCL-711 and 711b, ADLink ACL-8112
+ * Devices: (Advantech) PCL-711 [pcl711]
+ *         (Advantech) PCL-711B [pcl711b]
+ *         (AdLink) ACL-8112HG [acl8112hg]
+ *         (AdLink) ACL-8112DG [acl8112dg]
+ * Author: David A. Schleef <ds@schleef.org>
+ *        Janne Jalkanen <jalkanen@cs.hut.fi>
+ *        Eric Bunn <ebu@cs.hut.fi>
+ * Updated:
+ * Status: mostly complete
+ *
+ * Configuration Options:
+ *   [0] - I/O port base
+ *   [1] - IRQ, optional
  */
 
 #include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/interrupt.h>
-#include "../comedidev.h"
 
-#include <linux/delay.h>
+#include "../comedidev.h"
 
 #include "comedi_fc.h"
 #include "8253.h"
 
-#define PCL711_SIZE 16
-
-#define PCL711_CTR0 0
-#define PCL711_CTR1 1
-#define PCL711_CTR2 2
-#define PCL711_CTRCTL 3
-#define PCL711_AD_LO 4
-#define PCL711_DA0_LO 4
-#define PCL711_AD_HI 5
-#define PCL711_DA0_HI 5
-#define PCL711_DI_LO 6
-#define PCL711_DA1_LO 6
-#define PCL711_DI_HI 7
-#define PCL711_DA1_HI 7
-#define PCL711_CLRINTR 8
-#define PCL711_GAIN 9
-#define PCL711_MUX 10
-#define PCL711_MODE 11
-#define PCL711_SOFTTRIG 12
-#define PCL711_DO_LO 13
-#define PCL711_DO_HI 14
-
-static const struct comedi_lrange range_pcl711b_ai = { 5, {
-                                                          BIP_RANGE(5),
-                                                          BIP_RANGE(2.5),
-                                                          BIP_RANGE(1.25),
-                                                          BIP_RANGE(0.625),
-                                                          BIP_RANGE(0.3125)
-                                                          }
+/*
+ * I/O port register map
+ */
+#define PCL711_TIMER_BASE      0x00
+#define PCL711_AI_LSB_REG      0x04
+#define PCL711_AI_MSB_REG      0x05
+#define PCL711_AI_MSB_DRDY     (1 << 4)
+#define PCL711_AO_LSB_REG(x)   (0x04 + ((x) * 2))
+#define PCL711_AO_MSB_REG(x)   (0x05 + ((x) * 2))
+#define PCL711_DI_LSB_REG      0x06
+#define PCL711_DI_MSB_REG      0x07
+#define PCL711_INT_STAT_REG    0x08
+#define PCL711_INT_STAT_CLR    (0 << 0)  /* any value will work */
+#define PCL711_AI_GAIN_REG     0x09
+#define PCL711_AI_GAIN(x)      (((x) & 0xf) << 0)
+#define PCL711_MUX_REG         0x0a
+#define PCL711_MUX_CHAN(x)     (((x) & 0xf) << 0)
+#define PCL711_MUX_CS0         (1 << 4)
+#define PCL711_MUX_CS1         (1 << 5)
+#define PCL711_MUX_DIFF                (PCL711_MUX_CS0 | PCL711_MUX_CS1)
+#define PCL711_MODE_REG                0x0b
+#define PCL711_MODE_DEFAULT    (0 << 0)
+#define PCL711_MODE_SOFTTRIG   (1 << 0)
+#define PCL711_MODE_EXT                (2 << 0)
+#define PCL711_MODE_EXT_IRQ    (3 << 0)
+#define PCL711_MODE_PACER      (4 << 0)
+#define PCL711_MODE_PACER_IRQ  (6 << 0)
+#define PCL711_MODE_IRQ(x)     (((x) & 0x7) << 4)
+#define PCL711_SOFTTRIG_REG    0x0c
+#define PCL711_SOFTTRIG                (0 << 0)  /* any value will work */
+#define PCL711_DO_LSB_REG      0x0d
+#define PCL711_DO_MSB_REG      0x0e
+
+static const struct comedi_lrange range_pcl711b_ai = {
+       5, {
+               BIP_RANGE(5),
+               BIP_RANGE(2.5),
+               BIP_RANGE(1.25),
+               BIP_RANGE(0.625),
+               BIP_RANGE(0.3125)
+       }
 };
 
-static const struct comedi_lrange range_acl8112hg_ai = { 12, {
-                                                             BIP_RANGE(5),
-                                                             BIP_RANGE(0.5),
-                                                             BIP_RANGE(0.05),
-                                                             BIP_RANGE(0.005),
-                                                             UNI_RANGE(10),
-                                                             UNI_RANGE(1),
-                                                             UNI_RANGE(0.1),
-                                                             UNI_RANGE(0.01),
-                                                             BIP_RANGE(10),
-                                                             BIP_RANGE(1),
-                                                             BIP_RANGE(0.1),
-                                                             BIP_RANGE(0.01)
-                                                             }
+static const struct comedi_lrange range_acl8112hg_ai = {
+       12, {
+               BIP_RANGE(5),
+               BIP_RANGE(0.5),
+               BIP_RANGE(0.05),
+               BIP_RANGE(0.005),
+               UNI_RANGE(10),
+               UNI_RANGE(1),
+               UNI_RANGE(0.1),
+               UNI_RANGE(0.01),
+               BIP_RANGE(10),
+               BIP_RANGE(1),
+               BIP_RANGE(0.1),
+               BIP_RANGE(0.01)
+       }
 };
 
-static const struct comedi_lrange range_acl8112dg_ai = { 9, {
-                                                            BIP_RANGE(5),
-                                                            BIP_RANGE(2.5),
-                                                            BIP_RANGE(1.25),
-                                                            BIP_RANGE(0.625),
-                                                            UNI_RANGE(10),
-                                                            UNI_RANGE(5),
-                                                            UNI_RANGE(2.5),
-                                                            UNI_RANGE(1.25),
-                                                            BIP_RANGE(10)
-                                                            }
+static const struct comedi_lrange range_acl8112dg_ai = {
+       9, {
+               BIP_RANGE(5),
+               BIP_RANGE(2.5),
+               BIP_RANGE(1.25),
+               BIP_RANGE(0.625),
+               UNI_RANGE(10),
+               UNI_RANGE(5),
+               UNI_RANGE(2.5),
+               UNI_RANGE(1.25),
+               BIP_RANGE(10)
+       }
 };
 
-/*
- * flags
- */
-
-#define PCL711_TIMEOUT 100
-#define PCL711_DRDY 0x10
-
-static const int i8253_osc_base = 500; /* 2 Mhz */
-
 struct pcl711_board {
-
        const char *name;
-       int is_pcl711b;
-       int is_8112;
-       int is_dg;
-       int n_ranges;
        int n_aichan;
        int n_aochan;
        int maxirq;
        const struct comedi_lrange *ai_range_type;
 };
 
-struct pcl711_private {
+static const struct pcl711_board boardtypes[] = {
+       {
+               .name           = "pcl711",
+               .n_aichan       = 8,
+               .n_aochan       = 1,
+               .ai_range_type  = &range_bipolar5,
+       }, {
+               .name           = "pcl711b",
+               .n_aichan       = 8,
+               .n_aochan       = 1,
+               .maxirq         = 7,
+               .ai_range_type  = &range_pcl711b_ai,
+       }, {
+               .name           = "acl8112hg",
+               .n_aichan       = 16,
+               .n_aochan       = 2,
+               .maxirq         = 15,
+               .ai_range_type  = &range_acl8112hg_ai,
+       }, {
+               .name           = "acl8112dg",
+               .n_aichan       = 16,
+               .n_aochan       = 2,
+               .maxirq         = 15,
+               .ai_range_type  = &range_acl8112dg_ai,
+       },
+};
 
-       int board;
-       int adchan;
-       int ntrig;
-       int aip[8];
-       int mode;
+struct pcl711_private {
+       unsigned int ntrig;
        unsigned int ao_readback[2];
        unsigned int divisor1;
        unsigned int divisor2;
 };
 
+static void pcl711_ai_set_mode(struct comedi_device *dev, unsigned int mode)
+{
+       /*
+        * The pcl711b board uses bits in the mode register to select the
+        * interrupt. The other boards supported by this driver all use
+        * jumpers on the board.
+        *
+        * Enables the interrupt when needed on the pcl711b board. These
+        * bits do nothing on the other boards.
+        */
+       if (mode == PCL711_MODE_EXT_IRQ || mode == PCL711_MODE_PACER_IRQ)
+               mode |= PCL711_MODE_IRQ(dev->irq);
+
+       outb(mode, dev->iobase + PCL711_MODE_REG);
+}
+
+static unsigned int pcl711_ai_get_sample(struct comedi_device *dev,
+                                        struct comedi_subdevice *s)
+{
+       unsigned int val;
+
+       val = inb(dev->iobase + PCL711_AI_MSB_REG) << 8;
+       val |= inb(dev->iobase + PCL711_AI_LSB_REG);
+
+       return val & s->maxdata;
+}
+
+static int pcl711_ai_cancel(struct comedi_device *dev,
+                           struct comedi_subdevice *s)
+{
+       outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG);
+       pcl711_ai_set_mode(dev, PCL711_MODE_SOFTTRIG);
+       return 0;
+}
+
 static irqreturn_t pcl711_interrupt(int irq, void *d)
 {
-       int lo, hi;
-       int data;
        struct comedi_device *dev = d;
-       const struct pcl711_board *board = comedi_board(dev);
        struct pcl711_private *devpriv = dev->private;
-       struct comedi_subdevice *s = &dev->subdevices[0];
+       struct comedi_subdevice *s = dev->read_subdev;
+       unsigned int data;
 
        if (!dev->attached) {
                comedi_error(dev, "spurious interrupt");
                return IRQ_HANDLED;
        }
 
-       hi = inb(dev->iobase + PCL711_AD_HI);
-       lo = inb(dev->iobase + PCL711_AD_LO);
-       outb(0, dev->iobase + PCL711_CLRINTR);
-
-       data = (hi << 8) | lo;
+       data = pcl711_ai_get_sample(dev, s);
 
-       /* FIXME! Nothing else sets ntrig! */
-       if (!(--devpriv->ntrig)) {
-               if (board->is_8112)
-                       outb(1, dev->iobase + PCL711_MODE);
-               else
-                       outb(0, dev->iobase + PCL711_MODE);
+       outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG);
 
-               s->async->events |= COMEDI_CB_EOA;
+       if (comedi_buf_put(s->async, data) == 0) {
+               s->async->events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+       } else {
+               s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+               if (s->async->cmd.stop_src == TRIG_COUNT &&
+                   !(--devpriv->ntrig)) {
+                       pcl711_ai_set_mode(dev, PCL711_MODE_SOFTTRIG);
+                       s->async->events |= COMEDI_CB_EOA;
+               }
        }
        comedi_event(dev, s);
        return IRQ_HANDLED;
 }
 
-static void pcl711_set_changain(struct comedi_device *dev, int chan)
+static void pcl711_set_changain(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               unsigned int chanspec)
 {
-       const struct pcl711_board *board = comedi_board(dev);
-       int chan_register;
-
-       outb(CR_RANGE(chan), dev->iobase + PCL711_GAIN);
-
-       chan_register = CR_CHAN(chan);
-
-       if (board->is_8112) {
+       unsigned int chan = CR_CHAN(chanspec);
+       unsigned int range = CR_RANGE(chanspec);
+       unsigned int aref = CR_AREF(chanspec);
+       unsigned int mux = 0;
+
+       outb(PCL711_AI_GAIN(range), dev->iobase + PCL711_AI_GAIN_REG);
+
+       if (s->n_chan > 8) {
+               /* Select the correct MPC508A chip */
+               if (aref == AREF_DIFF) {
+                       chan &= 0x7;
+                       mux |= PCL711_MUX_DIFF;
+               } else {
+                       if (chan < 8)
+                               mux |= PCL711_MUX_CS0;
+                       else
+                               mux |= PCL711_MUX_CS1;
+               }
+       }
+       outb(mux | PCL711_MUX_CHAN(chan), dev->iobase + PCL711_MUX_REG);
+}
 
-               /*
-                *  Set the correct channel.  The two channel banks are switched
-                *  using the mask value.
-                *  NB: To use differential channels, you should use
-                *  mask = 0x30, but I haven't written the support for this
-                *  yet. /JJ
-                */
+static int pcl711_ai_wait_for_eoc(struct comedi_device *dev,
+                                 unsigned int timeout)
+{
+       unsigned int msb;
 
-               if (chan_register >= 8)
-                       chan_register = 0x20 | (chan_register & 0x7);
-               else
-                       chan_register |= 0x10;
-       } else {
-               outb(chan_register, dev->iobase + PCL711_MUX);
+       while (timeout--) {
+               msb = inb(dev->iobase + PCL711_AI_MSB_REG);
+               if ((msb & PCL711_AI_MSB_DRDY) == 0)
+                       return 0;
+               udelay(1);
        }
+       return -ETIME;
 }
 
-static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int pcl711_ai_insn_read(struct comedi_device *dev,
+                              struct comedi_subdevice *s,
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       const struct pcl711_board *board = comedi_board(dev);
-       int i, n;
-       int hi, lo;
-
-       pcl711_set_changain(dev, insn->chanspec);
-
-       for (n = 0; n < insn->n; n++) {
-               /*
-                *  Write the correct mode (software polling) and start polling
-                *  by writing to the trigger register
-                */
-               outb(1, dev->iobase + PCL711_MODE);
-
-               if (!board->is_8112)
-                       outb(0, dev->iobase + PCL711_SOFTTRIG);
-
-               i = PCL711_TIMEOUT;
-               while (--i) {
-                       hi = inb(dev->iobase + PCL711_AD_HI);
-                       if (!(hi & PCL711_DRDY))
-                               goto ok;
-                       udelay(1);
-               }
-               printk(KERN_ERR "comedi%d: pcl711: A/D timeout\n", dev->minor);
-               return -ETIME;
+       int ret;
+       int i;
+
+       pcl711_set_changain(dev, s, insn->chanspec);
 
-ok:
-               lo = inb(dev->iobase + PCL711_AD_LO);
+       pcl711_ai_set_mode(dev, PCL711_MODE_SOFTTRIG);
 
-               data[n] = ((hi & 0xf) << 8) | lo;
+       for (i = 0; i < insn->n; i++) {
+               outb(PCL711_SOFTTRIG, dev->iobase + PCL711_SOFTTRIG_REG);
+
+               ret = pcl711_ai_wait_for_eoc(dev, 100);
+               if (ret)
+                       return ret;
+
+               data[i] = pcl711_ai_get_sample(dev, s);
        }
 
-       return n;
+       return insn->n;
 }
 
 static int pcl711_ai_cmdtest(struct comedi_device *dev,
@@ -292,7 +329,6 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev,
                err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
        } else {
 #define MAX_SPEED 1000
-#define TIMER_BASE 100
                err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
                                                 MAX_SPEED);
        }
@@ -313,11 +349,11 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
                tmp = cmd->scan_begin_arg;
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                              &devpriv->divisor1,
-                                              &devpriv->divisor2,
-                                              &cmd->scan_begin_arg,
-                                              cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(I8254_OSC_BASE_2MHZ,
+                                         &devpriv->divisor1,
+                                         &devpriv->divisor2,
+                                         &cmd->scan_begin_arg,
+                                         cmd->flags);
                if (tmp != cmd->scan_begin_arg)
                        err++;
        }
@@ -331,110 +367,106 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev,
 static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        struct pcl711_private *devpriv = dev->private;
-       int timer1, timer2;
        struct comedi_cmd *cmd = &s->async->cmd;
 
-       pcl711_set_changain(dev, cmd->chanlist[0]);
+       pcl711_set_changain(dev, s, cmd->chanlist[0]);
+
+       if (cmd->stop_src == TRIG_COUNT) {
+               if (cmd->stop_arg == 0) {
+                       /* an empty acquisition */
+                       s->async->events |= COMEDI_CB_EOA;
+                       comedi_event(dev, s);
+                       return 0;
+               }
+               devpriv->ntrig = cmd->stop_arg;
+       }
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
-               /*
-                *  Set timers
-                *      timer chip is an 8253, with timers 1 and 2
-                *      cascaded
-                *  0x74 = Select Counter 1 | LSB/MSB | Mode=2 | Binary
-                *        Mode 2 = Rate generator
-                *
-                *  0xb4 = Select Counter 2 | LSB/MSB | Mode=2 | Binary
-                */
-
-               timer1 = timer2 = 0;
-               i8253_cascade_ns_to_timer(i8253_osc_base, &timer1, &timer2,
-                                         &cmd->scan_begin_arg,
-                                         TRIG_ROUND_NEAREST);
-
-               outb(0x74, dev->iobase + PCL711_CTRCTL);
-               outb(timer1 & 0xff, dev->iobase + PCL711_CTR1);
-               outb((timer1 >> 8) & 0xff, dev->iobase + PCL711_CTR1);
-               outb(0xb4, dev->iobase + PCL711_CTRCTL);
-               outb(timer2 & 0xff, dev->iobase + PCL711_CTR2);
-               outb((timer2 >> 8) & 0xff, dev->iobase + PCL711_CTR2);
-
-               /* clear pending interrupts (just in case) */
-               outb(0, dev->iobase + PCL711_CLRINTR);
-
-               /*
-                *  Set mode to IRQ transfer
-                */
-               outb(devpriv->mode | 6, dev->iobase + PCL711_MODE);
+               i8254_load(dev->iobase + PCL711_TIMER_BASE, 0,
+                          1, devpriv->divisor1, I8254_MODE2 | I8254_BINARY);
+               i8254_load(dev->iobase + PCL711_TIMER_BASE, 0,
+                          2, devpriv->divisor2, I8254_MODE2 | I8254_BINARY);
+
+               outb(PCL711_INT_STAT_CLR, dev->iobase + PCL711_INT_STAT_REG);
+
+               pcl711_ai_set_mode(dev, PCL711_MODE_PACER_IRQ);
        } else {
-               /* external trigger */
-               outb(devpriv->mode | 3, dev->iobase + PCL711_MODE);
+               pcl711_ai_set_mode(dev, PCL711_MODE_EXT_IRQ);
        }
 
        return 0;
 }
 
-/*
-   analog output
-*/
-static int pcl711_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static void pcl711_ao_write(struct comedi_device *dev,
+                           unsigned int chan, unsigned int val)
 {
-       struct pcl711_private *devpriv = dev->private;
-       int n;
-       int chan = CR_CHAN(insn->chanspec);
+       outb(val & 0xff, dev->iobase + PCL711_AO_LSB_REG(chan));
+       outb((val >> 8) & 0xff, dev->iobase + PCL711_AO_MSB_REG(chan));
+}
 
-       for (n = 0; n < insn->n; n++) {
-               outb((data[n] & 0xff),
-                    dev->iobase + (chan ? PCL711_DA1_LO : PCL711_DA0_LO));
-               outb((data[n] >> 8),
-                    dev->iobase + (chan ? PCL711_DA1_HI : PCL711_DA0_HI));
+static int pcl711_ao_insn_write(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
+{
+       struct pcl711_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int val = devpriv->ao_readback[chan];
+       int i;
 
-               devpriv->ao_readback[chan] = data[n];
+       for (i = 0; i < insn->n; i++) {
+               val = data[i];
+               pcl711_ao_write(dev, chan, val);
        }
+       devpriv->ao_readback[chan] = val;
 
-       return n;
+       return insn->n;
 }
 
 static int pcl711_ao_insn_read(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct pcl711_private *devpriv = dev->private;
-       int n;
-       int chan = CR_CHAN(insn->chanspec);
-
-       for (n = 0; n < insn->n; n++)
-               data[n] = devpriv->ao_readback[chan];
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       int i;
 
-       return n;
+       for (i = 0; i < insn->n; i++)
+               data[i] = devpriv->ao_readback[chan];
 
+       return insn->n;
 }
 
-/* Digital port read - Untested on 8112 */
 static int pcl711_di_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       data[1] = inb(dev->iobase + PCL711_DI_LO) |
-           (inb(dev->iobase + PCL711_DI_HI) << 8);
+       unsigned int val;
+
+       val = inb(dev->iobase + PCL711_DI_LSB_REG);
+       val |= (inb(dev->iobase + PCL711_DI_MSB_REG) << 8);
+
+       data[1] = val;
 
        return insn->n;
 }
 
-/* Digital port write - Untested on 8112 */
 static int pcl711_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       unsigned int mask;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               if (mask & 0x00ff)
+                       outb(s->state & 0xff, dev->iobase + PCL711_DO_LSB_REG);
+               if (mask & 0xff00)
+                       outb((s->state >> 8), dev->iobase + PCL711_DO_MSB_REG);
        }
-       if (data[0] & 0x00ff)
-               outb(s->state & 0xff, dev->iobase + PCL711_DO_LO);
-       if (data[0] & 0xff00)
-               outb((s->state >> 8), dev->iobase + PCL711_DO_HI);
 
        data[1] = s->state;
 
@@ -445,112 +477,82 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
        const struct pcl711_board *board = comedi_board(dev);
        struct pcl711_private *devpriv;
-       int ret;
-       unsigned int irq;
        struct comedi_subdevice *s;
+       int ret;
+
+       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
+       if (!devpriv)
+               return -ENOMEM;
 
-       ret = comedi_request_region(dev, it->options[0], PCL711_SIZE);
+       ret = comedi_request_region(dev, it->options[0], 0x10);
        if (ret)
                return ret;
 
-       /* grab our IRQ */
-       irq = it->options[1];
-       if (irq > board->maxirq) {
-               printk(KERN_ERR "irq out of range\n");
-               return -EINVAL;
-       }
-       if (irq) {
-               if (request_irq(irq, pcl711_interrupt, 0, dev->board_name,
-                               dev)) {
-                       printk(KERN_ERR "unable to allocate irq %u\n", irq);
-                       return -EINVAL;
-               } else {
-                       printk(KERN_INFO "( irq = %u )\n", irq);
-               }
+       if (it->options[1] && it->options[1] <= board->maxirq) {
+               ret = request_irq(it->options[1], pcl711_interrupt, 0,
+                                 dev->board_name, dev);
+               if (ret == 0)
+                       dev->irq = it->options[1];
        }
-       dev->irq = irq;
 
        ret = comedi_alloc_subdevices(dev, 4);
        if (ret)
                return ret;
 
-       devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
-       if (!devpriv)
-               return -ENOMEM;
-
+       /* Analog Input subdevice */
        s = &dev->subdevices[0];
-       /* AI subdevice */
-       s->type = COMEDI_SUBD_AI;
-       s->subdev_flags = SDF_READABLE | SDF_GROUND;
-       s->n_chan = board->n_aichan;
-       s->maxdata = 0xfff;
-       s->len_chanlist = 1;
-       s->range_table = board->ai_range_type;
-       s->insn_read = pcl711_ai_insn;
-       if (irq) {
+       s->type         = COMEDI_SUBD_AI;
+       s->subdev_flags = SDF_READABLE | SDF_GROUND;
+       if (board->n_aichan > 8)
+               s->subdev_flags |= SDF_DIFF;
+       s->n_chan       = board->n_aichan;
+       s->maxdata      = 0xfff;
+       s->range_table  = board->ai_range_type;
+       s->insn_read    = pcl711_ai_insn_read;
+       if (dev->irq) {
                dev->read_subdev = s;
-               s->subdev_flags |= SDF_CMD_READ;
-               s->do_cmdtest = pcl711_ai_cmdtest;
-               s->do_cmd = pcl711_ai_cmd;
+               s->subdev_flags |= SDF_CMD_READ;
+               s->len_chanlist = 1;
+               s->do_cmdtest   = pcl711_ai_cmdtest;
+               s->do_cmd       = pcl711_ai_cmd;
+               s->cancel       = pcl711_ai_cancel;
        }
 
+       /* Analog Output subdevice */
        s = &dev->subdevices[1];
-       /* AO subdevice */
-       s->type = COMEDI_SUBD_AO;
-       s->subdev_flags = SDF_WRITABLE;
-       s->n_chan = board->n_aochan;
-       s->maxdata = 0xfff;
-       s->len_chanlist = 1;
-       s->range_table = &range_bipolar5;
-       s->insn_write = pcl711_ao_insn;
-       s->insn_read = pcl711_ao_insn_read;
-
+       s->type         = COMEDI_SUBD_AO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = board->n_aochan;
+       s->maxdata      = 0xfff;
+       s->range_table  = &range_bipolar5;
+       s->insn_write   = pcl711_ao_insn_write;
+       s->insn_read    = pcl711_ao_insn_read;
+
+       /* Digital Input subdevice */
        s = &dev->subdevices[2];
-       /* 16-bit digital input */
-       s->type = COMEDI_SUBD_DI;
-       s->subdev_flags = SDF_READABLE;
-       s->n_chan = 16;
-       s->maxdata = 1;
-       s->len_chanlist = 16;
-       s->range_table = &range_digital;
-       s->insn_bits = pcl711_di_insn_bits;
-
+       s->type         = COMEDI_SUBD_DI;
+       s->subdev_flags = SDF_READABLE;
+       s->n_chan       = 16;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = pcl711_di_insn_bits;
+
+       /* Digital Output subdevice */
        s = &dev->subdevices[3];
-       /* 16-bit digital out */
-       s->type = COMEDI_SUBD_DO;
-       s->subdev_flags = SDF_WRITABLE;
-       s->n_chan = 16;
-       s->maxdata = 1;
-       s->len_chanlist = 16;
-       s->range_table = &range_digital;
-       s->state = 0;
-       s->insn_bits = pcl711_do_insn_bits;
-
-       /*
-          this is the "base value" for the mode register, which is
-          used for the irq on the PCL711
-        */
-       if (board->is_pcl711b)
-               devpriv->mode = (dev->irq << 4);
+       s->type         = COMEDI_SUBD_DO;
+       s->subdev_flags = SDF_WRITABLE;
+       s->n_chan       = 16;
+       s->maxdata      = 1;
+       s->range_table  = &range_digital;
+       s->insn_bits    = pcl711_do_insn_bits;
 
        /* clear DAC */
-       outb(0, dev->iobase + PCL711_DA0_LO);
-       outb(0, dev->iobase + PCL711_DA0_HI);
-       outb(0, dev->iobase + PCL711_DA1_LO);
-       outb(0, dev->iobase + PCL711_DA1_HI);
-
-       printk(KERN_INFO "\n");
+       pcl711_ao_write(dev, 0, 0x0);
+       pcl711_ao_write(dev, 1, 0x0);
 
        return 0;
 }
 
-static const struct pcl711_board boardtypes[] = {
-       { "pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5 },
-       { "pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai },
-       { "acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai },
-       { "acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai },
-};
-
 static struct comedi_driver pcl711_driver = {
        .driver_name    = "pcl711",
        .module         = THIS_MODULE,
@@ -563,5 +565,5 @@ static struct comedi_driver pcl711_driver = {
 module_comedi_driver(pcl711_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for PCL-711 compatible boards");
 MODULE_LICENSE("GPL");
index a4d0bcc31e52df22290fbfb174f08eac5f89f3c5..cf9568ee46e46f2bcb064c5339baebb3c007aa8e 100644 (file)
 /*
-    comedi/drivers/pcl726.c
-
-    hardware driver for Advantech cards:
-     card:   PCL-726, PCL-727, PCL-728
-     driver: pcl726,  pcl727,  pcl728
-    and for ADLink cards:
-     card:   ACL-6126, ACL-6128
-     driver: acl6126,  acl6128
-
-    COMEDI - Linux Control and Measurement Device Interface
-    Copyright (C) 1998 David A. Schleef <ds@schleef.org>
-
-    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.
-*/
-/*
-Driver: pcl726
-Description: Advantech PCL-726 & compatibles
-Author: ds
-Status: untested
-Devices: [Advantech] PCL-726 (pcl726), PCL-727 (pcl727), PCL-728 (pcl728),
-  [ADLink] ACL-6126 (acl6126), ACL-6128 (acl6128)
-
-Interrupts are not supported.
-
-    Options for PCL-726:
-     [0] - IO Base
-     [2]...[7] - D/A output range for channel 1-6:
-               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
-               4: 4-20mA, 5: unknown (external reference)
-
-    Options for PCL-727:
-     [0] - IO Base
-     [2]...[13] - D/A output range for channel 1-12:
-               0: 0-5V, 1: 0-10V, 2: +/-5V,
-               3: 4-20mA
-
-    Options for PCL-728 and ACL-6128:
-     [0] - IO Base
-     [2], [3] - D/A output range for channel 1 and 2:
-               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
-               4: 4-20mA, 5: 0-20mA
-
-    Options for ACL-6126:
-     [0] - IO Base
-     [1] - IRQ (0=disable, 3, 5, 6, 7, 9, 10, 11, 12, 15) (currently ignored)
-     [2]...[7] - D/A output range for channel 1-6:
-               0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
-               4: 4-20mA
-*/
+ * pcl726.c
+ * Comedi driver for 6/12-Channel D/A Output and DIO cards
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ *
+ * 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.
+ */
 
 /*
-    Thanks to Circuit Specialists for having programming info (!) on
-    their web page.  (http://www.cir.com/)
-*/
+ * Driver: pcl726
+ * Description: Advantech PCL-726 & compatibles
+ * Author: David A. Schleef <ds@schleef.org>
+ * Status: untested
+ * Devices: (Advantech) PCL-726 [pcl726]
+ *         (Advantech) PCL-727 [pcl727]
+ *         (Advantech) PCL-728 [pcl728]
+ *         (ADLink) ACL-6126 [acl6126]
+ *         (ADLink) ACL-6128 [acl6128]
+ *
+ * Configuration Options:
+ *   [0]  - IO Base
+ *   [1]  - IRQ (ACL-6126 only)
+ *   [2]  - D/A output range for channel 0
+ *   [3]  - D/A output range for channel 1
+ *
+ * Boards with > 2 analog output channels:
+ *   [4]  - D/A output range for channel 2
+ *   [5]  - D/A output range for channel 3
+ *   [6]  - D/A output range for channel 4
+ *   [7]  - D/A output range for channel 5
+ *
+ * Boards with > 6 analog output channels:
+ *   [8]  - D/A output range for channel 6
+ *   [9]  - D/A output range for channel 7
+ *   [10] - D/A output range for channel 8
+ *   [11] - D/A output range for channel 9
+ *   [12] - D/A output range for channel 10
+ *   [13] - D/A output range for channel 11
+ *
+ * For PCL-726 the D/A output ranges are:
+ *   0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, 4: 4-20mA, 5: unknown
+ *
+ * For PCL-727:
+ *   0: 0-5V, 1: 0-10V, 2: +/-5V, 3: 4-20mA
+ *
+ * For PCL-728 and ACL-6128:
+ *   0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, 4: 4-20mA, 5: 0-20mA
+ *
+ * For ACL-6126:
+ *   0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V, 4: 4-20mA
+ */
 
 #include <linux/module.h>
-#include "../comedidev.h"
-
-#undef ACL6126_IRQ             /* no interrupt support (yet) */
+#include <linux/interrupt.h>
 
-#define PCL726_SIZE 16
-#define PCL727_SIZE 32
-#define PCL728_SIZE 8
+#include "../comedidev.h"
 
-#define PCL726_DAC0_HI 0
-#define PCL726_DAC0_LO 1
+#include "comedi_fc.h"
 
-#define PCL726_DO_HI 12
-#define PCL726_DO_LO 13
-#define PCL726_DI_HI 14
-#define PCL726_DI_LO 15
+#define PCL726_AO_MSB_REG(x)   (0x00 + ((x) * 2))
+#define PCL726_AO_LSB_REG(x)   (0x01 + ((x) * 2))
+#define PCL726_DO_MSB_REG      0x0c
+#define PCL726_DO_LSB_REG      0x0d
+#define PCL726_DI_MSB_REG      0x0e
+#define PCL726_DI_LSB_REG      0x0f
 
-#define PCL727_DO_HI 24
-#define PCL727_DO_LO 25
-#define PCL727_DI_HI  0
-#define PCL727_DI_LO  1
+#define PCL727_DI_MSB_REG      0x00
+#define PCL727_DI_LSB_REG      0x01
+#define PCL727_DO_MSB_REG      0x18
+#define PCL727_DO_LSB_REG      0x19
 
 static const struct comedi_lrange *const rangelist_726[] = {
-       &range_unipolar5, &range_unipolar10,
-       &range_bipolar5, &range_bipolar10,
-       &range_4_20mA, &range_unknown
+       &range_unipolar5,
+       &range_unipolar10,
+       &range_bipolar5,
+       &range_bipolar10,
+       &range_4_20mA,
+       &range_unknown
 };
 
 static const struct comedi_lrange *const rangelist_727[] = {
-       &range_unipolar5, &range_unipolar10,
+       &range_unipolar5,
+       &range_unipolar10,
        &range_bipolar5,
        &range_4_20mA
 };
 
 static const struct comedi_lrange *const rangelist_728[] = {
-       &range_unipolar5, &range_unipolar10,
-       &range_bipolar5, &range_bipolar10,
-       &range_4_20mA, &range_0_20mA
+       &range_unipolar5,
+       &range_unipolar10,
+       &range_bipolar5,
+       &range_bipolar10,
+       &range_4_20mA,
+       &range_0_20mA
 };
 
 struct pcl726_board {
-
-       const char *name;       /*  driver name */
-       int n_aochan;           /*  num of D/A chans */
-       int num_of_ranges;      /*  num of ranges */
-       unsigned int IRQbits;   /*  allowed interrupts */
-       unsigned int io_range;  /*  len of IO space */
-       char have_dio;          /*  1=card have DI/DO ports */
-       int di_hi;              /*  ports for DI/DO operations */
-       int di_lo;
-       int do_hi;
-       int do_lo;
-       const struct comedi_lrange *const *range_type_list;
-       /*  list of supported ranges */
+       const char *name;
+       unsigned long io_len;
+       unsigned int irq_mask;
+       const struct comedi_lrange *const *ao_ranges;
+       int ao_num_ranges;
+       int ao_nchan;
+       unsigned int have_dio:1;
+       unsigned int is_pcl727:1;
 };
 
-static const struct pcl726_board boardtypes[] = {
-       {"pcl726", 6, 6, 0x0000, PCL726_SIZE, 1,
-        PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
-        &rangelist_726[0],},
-       {"pcl727", 12, 4, 0x0000, PCL727_SIZE, 1,
-        PCL727_DI_HI, PCL727_DI_LO, PCL727_DO_HI, PCL727_DO_LO,
-        &rangelist_727[0],},
-       {"pcl728", 2, 6, 0x0000, PCL728_SIZE, 0,
-        0, 0, 0, 0,
-        &rangelist_728[0],},
-       {"acl6126", 6, 5, 0x96e8, PCL726_SIZE, 1,
-        PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
-        &rangelist_726[0],},
-       {"acl6128", 2, 6, 0x0000, PCL728_SIZE, 0,
-        0, 0, 0, 0,
-        &rangelist_728[0],},
+static const struct pcl726_board pcl726_boards[] = {
+       {
+               .name           = "pcl726",
+               .io_len         = 0x10,
+               .ao_ranges      = &rangelist_726[0],
+               .ao_num_ranges  = ARRAY_SIZE(rangelist_726),
+               .ao_nchan       = 6,
+               .have_dio       = 1,
+       }, {
+               .name           = "pcl727",
+               .io_len         = 0x20,
+               .ao_ranges      = &rangelist_727[0],
+               .ao_num_ranges  = ARRAY_SIZE(rangelist_727),
+               .ao_nchan       = 12,
+               .have_dio       = 1,
+               .is_pcl727      = 1,
+       }, {
+               .name           = "pcl728",
+               .io_len         = 0x08,
+               .ao_num_ranges  = ARRAY_SIZE(rangelist_728),
+               .ao_ranges      = &rangelist_728[0],
+               .ao_nchan       = 2,
+       }, {
+               .name           = "acl6126",
+               .io_len         = 0x10,
+               .irq_mask       = 0x96e8,
+               .ao_num_ranges  = ARRAY_SIZE(rangelist_726),
+               .ao_ranges      = &rangelist_726[0],
+               .ao_nchan       = 6,
+               .have_dio       = 1,
+       }, {
+               .name           = "acl6128",
+               .io_len         = 0x08,
+               .ao_num_ranges  = ARRAY_SIZE(rangelist_728),
+               .ao_ranges      = &rangelist_728[0],
+               .ao_nchan       = 2,
+       },
 };
 
 struct pcl726_private {
-
-       int bipolar[12];
        const struct comedi_lrange *rangelist[12];
        unsigned int ao_readback[12];
+       unsigned int cmd_running:1;
 };
 
-static int pcl726_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-                         struct comedi_insn *insn, unsigned int *data)
+static int pcl726_intr_insn_bits(struct comedi_device *dev,
+                                struct comedi_subdevice *s,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
+{
+       data[1] = 0;
+       return insn->n;
+}
+
+static int pcl726_intr_cmdtest(struct comedi_device *dev,
+                              struct comedi_subdevice *s,
+                              struct comedi_cmd *cmd)
+{
+       int err = 0;
+
+       /* Step 1 : check if triggers are trivially valid */
+
+       err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
+       err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
+       err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW);
+       err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
+       err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE);
+
+       if (err)
+               return 1;
+
+       /* Step 2a : make sure trigger sources are unique */
+       /* Step 2b : and mutually compatible */
+
+       if (err)
+               return 2;
+
+       /* Step 3: check if arguments are trivially valid */
+
+       err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
+       err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+       err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
+
+       if (err)
+               return 3;
+
+       /* step 4: ignored */
+
+       if (err)
+               return 4;
+
+       return 0;
+}
+
+static int pcl726_intr_cmd(struct comedi_device *dev,
+                          struct comedi_subdevice *s)
+{
+       struct pcl726_private *devpriv = dev->private;
+
+       devpriv->cmd_running = 1;
+
+       return 0;
+}
+
+static int pcl726_intr_cancel(struct comedi_device *dev,
+                             struct comedi_subdevice *s)
 {
        struct pcl726_private *devpriv = dev->private;
-       int hi, lo;
-       int n;
-       int chan = CR_CHAN(insn->chanspec);
-
-       for (n = 0; n < insn->n; n++) {
-               lo = data[n] & 0xff;
-               hi = (data[n] >> 8) & 0xf;
-               if (devpriv->bipolar[chan])
-                       hi ^= 0x8;
-               /*
-                * the programming info did not say which order
-                * to write bytes.  switch the order of the next
-                * two lines if you get glitches.
-                */
-               outb(hi, dev->iobase + PCL726_DAC0_HI + 2 * chan);
-               outb(lo, dev->iobase + PCL726_DAC0_LO + 2 * chan);
-               devpriv->ao_readback[chan] = data[n];
+
+       devpriv->cmd_running = 0;
+
+       return 0;
+}
+
+static irqreturn_t pcl726_interrupt(int irq, void *d)
+{
+       struct comedi_device *dev = d;
+       struct comedi_subdevice *s = dev->read_subdev;
+       struct pcl726_private *devpriv = dev->private;
+
+       if (devpriv->cmd_running) {
+               pcl726_intr_cancel(dev, s);
+
+               comedi_buf_put(s->async, 0);
+               s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+               comedi_event(dev, s);
        }
 
-       return n;
+       return IRQ_HANDLED;
+}
+
+static int pcl726_ao_insn_write(struct comedi_device *dev,
+                               struct comedi_subdevice *s,
+                               struct comedi_insn *insn,
+                               unsigned int *data)
+{
+       struct pcl726_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int range = CR_RANGE(insn->chanspec);
+       unsigned int val;
+       int i;
+
+       for (i = 0; i < insn->n; i++) {
+               val = data[i];
+               devpriv->ao_readback[chan] = val;
+
+               /* bipolar data to the DAC is two's complement */
+               if (comedi_chan_range_is_bipolar(s, chan, range))
+                       val = comedi_offset_munge(s, val);
+
+               /* order is important, MSB then LSB */
+               outb((val >> 8) & 0xff, dev->iobase + PCL726_AO_MSB_REG(chan));
+               outb(val & 0xff, dev->iobase + PCL726_AO_LSB_REG(chan));
+       }
+
+       return insn->n;
 }
 
 static int pcl726_ao_insn_read(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct pcl726_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
-       int n;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       int i;
+
+       for (i = 0; i < insn->n; i++)
+               data[i] = devpriv->ao_readback[chan];
 
-       for (n = 0; n < insn->n; n++)
-               data[n] = devpriv->ao_readback[chan];
-       return n;
+       return insn->n;
 }
 
 static int pcl726_di_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        const struct pcl726_board *board = comedi_board(dev);
+       unsigned int val;
 
-       data[1] = inb(dev->iobase + board->di_lo) |
-           (inb(dev->iobase + board->di_hi) << 8);
+       if (board->is_pcl727) {
+               val = inb(dev->iobase + PCL727_DI_LSB_REG);
+               val |= (inb(dev->iobase + PCL727_DI_MSB_REG) << 8);
+       } else {
+               val = inb(dev->iobase + PCL726_DI_LSB_REG);
+               val |= (inb(dev->iobase + PCL726_DI_MSB_REG) << 8);
+       }
+
+       data[1] = val;
 
        return insn->n;
 }
 
 static int pcl726_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        const struct pcl726_board *board = comedi_board(dev);
-
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       unsigned long io = dev->iobase;
+       unsigned int mask;
+
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
+               if (board->is_pcl727) {
+                       if (mask & 0x00ff)
+                               outb(s->state & 0xff, io + PCL727_DO_LSB_REG);
+                       if (mask & 0xff00)
+                               outb((s->state >> 8), io + PCL727_DO_MSB_REG);
+               } else {
+                       if (mask & 0x00ff)
+                               outb(s->state & 0xff, io + PCL726_DO_LSB_REG);
+                       if (mask & 0xff00)
+                               outb((s->state >> 8), io + PCL726_DO_MSB_REG);
+               }
        }
-       if (data[1] & 0x00ff)
-               outb(s->state & 0xff, dev->iobase + board->do_lo);
-       if (data[1] & 0xff00)
-               outb((s->state >> 8), dev->iobase + board->do_hi);
 
        data[1] = s->state;
 
        return insn->n;
 }
 
-static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pcl726_attach(struct comedi_device *dev,
+                        struct comedi_devconfig *it)
 {
        const struct pcl726_board *board = comedi_board(dev);
        struct pcl726_private *devpriv;
        struct comedi_subdevice *s;
-       int ret, i;
-#ifdef ACL6126_IRQ
-       unsigned int irq;
-#endif
+       int subdev;
+       int ret;
+       int i;
 
-       ret = comedi_request_region(dev, it->options[0], board->io_range);
+       ret = comedi_request_region(dev, it->options[0], board->io_len);
        if (ret)
                return ret;
 
@@ -232,97 +358,81 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        if (!devpriv)
                return -ENOMEM;
 
-       for (i = 0; i < 12; i++) {
-               devpriv->bipolar[i] = 0;
-               devpriv->rangelist[i] = &range_unknown;
-       }
-
-#ifdef ACL6126_IRQ
-       irq = 0;
-       if (boardtypes[board].IRQbits != 0) {   /* board support IRQ */
-               irq = it->options[1];
-               devpriv->first_chan = 2;
-               if (irq) {      /* we want to use IRQ */
-                       if (((1 << irq) & boardtypes[board].IRQbits) == 0) {
-                               printk(KERN_WARNING
-                                       ", IRQ %d is out of allowed range,"
-                                       " DISABLING IT", irq);
-                               irq = 0;        /* Bad IRQ */
-                       } else {
-                               if (request_irq(irq, interrupt_pcl818, 0,
-                                               dev->board_name, dev)) {
-                                       printk(KERN_WARNING
-                                               ", unable to allocate IRQ %d,"
-                                               " DISABLING IT", irq);
-                                       irq = 0;        /* Can't use IRQ */
-                               } else {
-                                       printk(", irq=%d", irq);
-                               }
-                       }
+       /*
+        * Hook up the external trigger source interrupt only if the
+        * user config option is valid and the board supports interrupts.
+        */
+       if (it->options[1] && (board->irq_mask & (1 << it->options[1]))) {
+               ret = request_irq(it->options[1], pcl726_interrupt, 0,
+                                 dev->board_name, dev);
+               if (ret == 0) {
+                       /* External trigger source is from Pin-17 of CN3 */
+                       dev->irq = it->options[1];
                }
        }
 
-       dev->irq = irq;
-#endif
+       /* setup the per-channel analog output range_table_list */
+       for (i = 0; i < 12; i++) {
+               unsigned int opt = it->options[2 + i];
 
-       printk("\n");
+               if (opt < board->ao_num_ranges && i < board->ao_nchan)
+                       devpriv->rangelist[i] = board->ao_ranges[opt];
+               else
+                       devpriv->rangelist[i] = &range_unknown;
+       }
 
-       ret = comedi_alloc_subdevices(dev, 3);
+       subdev = board->have_dio ? 3 : 1;
+       if (dev->irq)
+               subdev++;
+       ret = comedi_alloc_subdevices(dev, subdev);
        if (ret)
                return ret;
 
-       s = &dev->subdevices[0];
-       /* ao */
-       s->type = COMEDI_SUBD_AO;
-       s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
-       s->n_chan = board->n_aochan;
-       s->maxdata = 0xfff;
-       s->len_chanlist = 1;
-       s->insn_write = pcl726_ao_insn;
-       s->insn_read = pcl726_ao_insn_read;
-       s->range_table_list = devpriv->rangelist;
-       for (i = 0; i < board->n_aochan; i++) {
-               int j;
-
-               j = it->options[2 + 1];
-               if ((j < 0) || (j >= board->num_of_ranges)) {
-                       printk
-                           ("Invalid range for channel %d! Must be 0<=%d<%d\n",
-                            i, j, board->num_of_ranges - 1);
-                       j = 0;
-               }
-               devpriv->rangelist[i] = board->range_type_list[j];
-               if (devpriv->rangelist[i]->range[0].min ==
-                   -devpriv->rangelist[i]->range[0].max)
-                       devpriv->bipolar[i] = 1;        /* bipolar range */
-       }
+       subdev = 0;
 
-       s = &dev->subdevices[1];
-       /* di */
-       if (!board->have_dio) {
-               s->type = COMEDI_SUBD_UNUSED;
-       } else {
-               s->type = COMEDI_SUBD_DI;
-               s->subdev_flags = SDF_READABLE | SDF_GROUND;
-               s->n_chan = 16;
-               s->maxdata = 1;
-               s->len_chanlist = 1;
-               s->insn_bits = pcl726_di_insn_bits;
-               s->range_table = &range_digital;
+       /* Analog Output subdevice */
+       s = &dev->subdevices[subdev++];
+       s->type         = COMEDI_SUBD_AO;
+       s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+       s->n_chan       = board->ao_nchan;
+       s->maxdata      = 0x0fff;
+       s->range_table_list = devpriv->rangelist;
+       s->insn_write   = pcl726_ao_insn_write;
+       s->insn_read    = pcl726_ao_insn_read;
+
+       if (board->have_dio) {
+               /* Digital Input subdevice */
+               s = &dev->subdevices[subdev++];
+               s->type         = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE;
+               s->n_chan       = 16;
+               s->maxdata      = 1;
+               s->insn_bits    = pcl726_di_insn_bits;
+               s->range_table  = &range_digital;
+
+               /* Digital Output subdevice */
+               s = &dev->subdevices[subdev++];
+               s->type         = COMEDI_SUBD_DO;
+               s->subdev_flags = SDF_WRITABLE;
+               s->n_chan       = 16;
+               s->maxdata      = 1;
+               s->insn_bits    = pcl726_do_insn_bits;
+               s->range_table  = &range_digital;
        }
 
-       s = &dev->subdevices[2];
-       /* do */
-       if (!board->have_dio) {
-               s->type = COMEDI_SUBD_UNUSED;
-       } else {
-               s->type = COMEDI_SUBD_DO;
-               s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
-               s->n_chan = 16;
-               s->maxdata = 1;
-               s->len_chanlist = 1;
-               s->insn_bits = pcl726_do_insn_bits;
-               s->range_table = &range_digital;
+       if (dev->irq) {
+               /* Digial Input subdevice - Interrupt support */
+               s = &dev->subdevices[subdev++];
+               dev->read_subdev = s;
+               s->type         = COMEDI_SUBD_DI;
+               s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+               s->n_chan       = 1;
+               s->maxdata      = 1;
+               s->range_table  = &range_digital;
+               s->insn_bits    = pcl726_intr_insn_bits;
+               s->do_cmdtest   = pcl726_intr_cmdtest;
+               s->do_cmd       = pcl726_intr_cmd;
+               s->cancel       = pcl726_intr_cancel;
        }
 
        return 0;
@@ -333,12 +443,12 @@ static struct comedi_driver pcl726_driver = {
        .module         = THIS_MODULE,
        .attach         = pcl726_attach,
        .detach         = comedi_legacy_detach,
-       .board_name     = &boardtypes[0].name,
-       .num_names      = ARRAY_SIZE(boardtypes),
+       .board_name     = &pcl726_boards[0].name,
+       .num_names      = ARRAY_SIZE(pcl726_boards),
        .offset         = sizeof(struct pcl726_board),
 };
 module_comedi_driver(pcl726_driver);
 
 MODULE_AUTHOR("Comedi http://www.comedi.org");
-MODULE_DESCRIPTION("Comedi low-level driver");
+MODULE_DESCRIPTION("Comedi driver for Advantech PCL-726 & compatibles");
 MODULE_LICENSE("GPL");
index 2a659f23ecda78be31cbb369c735c543c8218616..d041b714db29732f91e8739db8dcf1122f55d55b 100644 (file)
@@ -167,20 +167,17 @@ static int pcl730_do_insn_bits(struct comedi_device *dev,
                               unsigned int *data)
 {
        unsigned long reg = (unsigned long)s->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
+       unsigned int mask;
 
+       mask = comedi_dio_update_state(s, data);
        if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
                if (mask & 0x00ff)
                        outb(s->state & 0xff, dev->iobase + reg);
-               if ((mask & 0xff00) && (s->n_chan > 8))
+               if ((mask & 0xff00) & (s->n_chan > 8))
                        outb((s->state >> 8) & 0xff, dev->iobase + reg + 1);
-               if ((mask & 0xff0000) && (s->n_chan > 16))
+               if ((mask & 0xff0000) & (s->n_chan > 16))
                        outb((s->state >> 16) & 0xff, dev->iobase + reg + 2);
-               if ((mask & 0xff000000) && (s->n_chan > 24))
+               if ((mask & 0xff000000) & (s->n_chan > 24))
                        outb((s->state >> 24) & 0xff, dev->iobase + reg + 3);
        }
 
index 03a098900d34eca1acdda953983c3004f8f59cca..03315abcca1918ab8887caf2ac6739ec4fd76376 100644 (file)
@@ -355,7 +355,6 @@ struct pcl812_private {
        unsigned int ai_n_chan; /*  how many channels is measured */
        unsigned int ai_flags;  /*  flaglist */
        unsigned int ai_data_len;       /*  len of data buffer */
-       short *ai_data;         /*  data buffer */
        unsigned int ai_is16b;  /*  =1 we have 16 bit card */
        unsigned long dmabuf[2];        /*  PTR to DMA buf */
        unsigned int dmapages[2];       /*  how many pages we have allocated */
@@ -509,19 +508,16 @@ static int pcl812_di_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pcl812_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       if (comedi_dio_update_state(s, data)) {
                outb(s->state & 0xff, dev->iobase + PCL812_DO_LO);
                outb((s->state >> 8), dev->iobase + PCL812_DO_HI);
        }
+
        data[1] = s->state;
 
        return insn->n;
@@ -592,9 +588,9 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev,
 
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer(board->i8254_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(board->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (cmd->convert_arg < board->ai_ns_min)
                        cmd->convert_arg = board->ai_ns_min;
                if (tmp != cmd->convert_arg)
@@ -640,8 +636,7 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                        cmd->convert_arg = board->ai_ns_min;
                i8253_cascade_ns_to_timer(board->i8254_osc_base,
                                          &divisor1, &divisor2,
-                                         &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+                                         &cmd->convert_arg, cmd->flags);
        }
 
        start_pacer(dev, -1, 0, 0);     /*  stop pacer */
@@ -665,7 +660,6 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
        devpriv->ai_flags = cmd->flags;
        devpriv->ai_data_len = s->async->prealloc_bufsz;
-       devpriv->ai_data = s->async->prealloc_buf;
        if (cmd->stop_src == TRIG_COUNT) {
                devpriv->ai_scans = cmd->stop_arg;
                devpriv->ai_neverending = 0;
@@ -835,7 +829,8 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
 ==============================================================================
 */
 static void transfer_from_dma_buf(struct comedi_device *dev,
-                                 struct comedi_subdevice *s, short *ptr,
+                                 struct comedi_subdevice *s,
+                                 unsigned short *ptr,
                                  unsigned int bufptr, unsigned int len)
 {
        struct pcl812_private *devpriv = dev->private;
@@ -873,9 +868,9 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
        struct comedi_subdevice *s = &dev->subdevices[0];
        unsigned long dma_flags;
        int len, bufptr;
-       short *ptr;
+       unsigned short *ptr;
 
-       ptr = (short *)devpriv->dmabuf[devpriv->next_dma_buf];
+       ptr = (unsigned short *)devpriv->dmabuf[devpriv->next_dma_buf];
        len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) -
            devpriv->ai_poll_ptr;
 
@@ -1443,40 +1438,40 @@ static void pcl812_detach(struct comedi_device *dev)
 
 static const struct pcl812_board boardtypes[] = {
        {"pcl812", boardPCL812, 16, 0, 2, 16, 16, 0x0fff,
-        33000, 500, &range_bipolar10, &range_unipolar5,
+        33000, I8254_OSC_BASE_2MHZ, &range_bipolar10, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"pcl812pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff,
-        33000, 500, &range_pcl812pg_ai, &range_unipolar5,
+        33000, I8254_OSC_BASE_2MHZ, &range_pcl812pg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"acl8112pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff,
-        10000, 500, &range_pcl812pg_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_pcl812pg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"acl8112dg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        10000, 500, &range_acl8112dg_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_acl8112dg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
        {"acl8112hg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        10000, 500, &range_acl8112hg_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_acl8112hg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
        {"a821pgl", boardA821, 16, 8, 1, 16, 16, 0x0fff,
-        10000, 500, &range_pcl813b_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_pcl813b_ai, &range_unipolar5,
         0x000c, 0x00, PCLx1x_IORANGE, 0},
        {"a821pglnda", boardA821, 16, 8, 0, 0, 0, 0x0fff,
-        10000, 500, &range_pcl813b_ai, NULL,
+        10000, I8254_OSC_BASE_2MHZ, &range_pcl813b_ai, NULL,
         0x000c, 0x00, PCLx1x_IORANGE, 0},
        {"a821pgh", boardA821, 16, 8, 1, 16, 16, 0x0fff,
-        10000, 500, &range_a821pgh_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_a821pgh_ai, &range_unipolar5,
         0x000c, 0x00, PCLx1x_IORANGE, 0},
        {"a822pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        10000, 500, &range_acl8112dg_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_acl8112dg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"a822pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        10000, 500, &range_acl8112hg_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_acl8112hg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"a823pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        8000, 500, &range_acl8112dg_ai, &range_unipolar5,
+        8000, I8254_OSC_BASE_2MHZ, &range_acl8112dg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"a823pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
-        8000, 500, &range_acl8112hg_ai, &range_unipolar5,
+        8000, I8254_OSC_BASE_2MHZ, &range_acl8112hg_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
        {"pcl813", boardPCL813, 32, 0, 0, 0, 0, 0x0fff,
         0, 0, &range_pcl813b_ai, NULL,
@@ -1491,10 +1486,10 @@ static const struct pcl812_board boardtypes[] = {
         0, 0, &range_iso813_1_ai, NULL,
         0x0000, 0x00, PCLx1x_IORANGE, 0},
        {"acl8216", boardACL8216, 16, 8, 2, 16, 16, 0xffff,
-        10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_pcl813b2_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
        {"a826pg", boardACL8216, 16, 8, 2, 16, 16, 0xffff,
-        10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+        10000, I8254_OSC_BASE_2MHZ, &range_pcl813b2_ai, &range_unipolar5,
         0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
 };
 
index f03134962596ccbe2254edaa7ab4eb04c688acaf..ab9d2bd26a207b11ff463f0952cf66f8d95cd456 100644 (file)
@@ -229,7 +229,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
        struct comedi_device *dev = d;
        struct pcl816_private *devpriv = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[0];
-       int low, hi;
+       unsigned char low, hi;
        int timeout = 50;       /* wait max 50us */
 
        while (timeout--) {
@@ -281,7 +281,8 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
    analog input dma mode 1 & 3, 816 cards
 */
 static void transfer_from_dma_buf(struct comedi_device *dev,
-                                 struct comedi_subdevice *s, short *ptr,
+                                 struct comedi_subdevice *s,
+                                 unsigned short *ptr,
                                  unsigned int bufptr, unsigned int len)
 {
        struct pcl816_private *devpriv = dev->private;
@@ -324,7 +325,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
        struct comedi_subdevice *s = &dev->subdevices[0];
        int len, bufptr, this_dma_buf;
        unsigned long dma_flags;
-       short *ptr;
+       unsigned short *ptr;
 
        disable_dma(devpriv->dma);
        this_dma_buf = devpriv->next_dma_buf;
@@ -352,7 +353,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
        devpriv->dma_runs_to_end--;
        outb(0, dev->iobase + PCL816_CLRINT);   /* clear INT request */
 
-       ptr = (short *)devpriv->dmabuf[this_dma_buf];
+       ptr = (unsigned short *)devpriv->dmabuf[this_dma_buf];
 
        len = (devpriv->hwdmasize[0] >> 1) - devpriv->ai_poll_ptr;
        bufptr = devpriv->ai_poll_ptr;
@@ -481,8 +482,7 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev,
                tmp = cmd->convert_arg;
                i8253_cascade_ns_to_timer(board->i8254_osc_base,
                                          &divisor1, &divisor2,
-                                         &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+                                         &cmd->convert_arg, cmd->flags);
                if (cmd->convert_arg < board->ai_ns_min)
                        cmd->convert_arg = board->ai_ns_min;
                if (tmp != cmd->convert_arg)
@@ -528,9 +528,9 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                if (cmd->convert_arg < board->ai_ns_min)
                        cmd->convert_arg = board->ai_ns_min;
 
-               i8253_cascade_ns_to_timer(board->i8254_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(board->i8254_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg, cmd->flags);
 
                /*  PCL816 crash if any divisor is set to 1 */
                if (divisor1 == 1) {
@@ -666,7 +666,8 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
        }
 
        transfer_from_dma_buf(dev, s,
-                             (short *)devpriv->dmabuf[devpriv->next_dma_buf],
+                             (unsigned short *)devpriv->dmabuf[devpriv->
+                                                               next_dma_buf],
                              devpriv->ai_poll_ptr, top2);
 
        devpriv->ai_poll_ptr = top1;    /*  new buffer position */
@@ -1105,7 +1106,7 @@ static const struct pcl816_board boardtypes[] = {
         0xffff,                /*  D/A maxdata */
         1024,
         1,                     /*  ao chan list */
-        100},
+        I8254_OSC_BASE_10MHZ},
        {"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816,
         &range_pcl816, PCLx1x_RANGE,
         0x00fc,
@@ -1114,7 +1115,7 @@ static const struct pcl816_board boardtypes[] = {
         0x3fff,
         1024,
         1,
-        100},
+        I8254_OSC_BASE_10MHZ},
 };
 
 static struct comedi_driver pcl816_driver = {
index a52ba82ff0e4a10adbdebf1508b73b1d7967c132..9e4d7e8605097bff47e0dedb3e605b90b170da06 100644 (file)
@@ -289,7 +289,6 @@ struct pcl818_private {
        unsigned int *ai_chanlist;      /*  actaul chanlist */
        unsigned int ai_flags;  /*  flaglist */
        unsigned int ai_data_len;       /*  len of data buffer */
-       short *ai_data;         /*  data buffer */
        unsigned int ai_timer1; /*  timers */
        unsigned int ai_timer2;
        struct comedi_subdevice *sub_ai;        /*  ptr to AI subdevice */
@@ -418,21 +417,15 @@ static int pcl818_di_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-   DIGITAL OUTPUT MODE0, 818 cards
-
-   only one sample per call is supported
-*/
 static int pcl818_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       s->state &= ~data[0];
-       s->state |= (data[0] & data[1]);
-
-       outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);
-       outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
+       if (comedi_dio_update_state(s, data)) {
+               outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);
+               outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
+       }
 
        data[1] = s->state;
 
@@ -449,7 +442,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
        struct comedi_device *dev = d;
        struct pcl818_private *devpriv = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[0];
-       int low;
+       unsigned char low;
        int timeout = 50;       /* wait max 50us */
 
        while (timeout--) {
@@ -511,7 +504,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
        struct comedi_subdevice *s = &dev->subdevices[0];
        int i, len, bufptr;
        unsigned long flags;
-       short *ptr;
+       unsigned short *ptr;
 
        disable_dma(devpriv->dma);
        devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
@@ -534,7 +527,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
 
        devpriv->dma_runs_to_end--;
        outb(0, dev->iobase + PCL818_CLRINT);   /* clear INT request */
-       ptr = (short *)devpriv->dmabuf[1 - devpriv->next_dma_buf];
+       ptr = (unsigned short *)devpriv->dmabuf[1 - devpriv->next_dma_buf];
 
        len = devpriv->hwdmasize[0] >> 1;
        bufptr = 0;
@@ -588,7 +581,8 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
        struct comedi_device *dev = d;
        struct pcl818_private *devpriv = dev->private;
        struct comedi_subdevice *s = &dev->subdevices[0];
-       int i, len, lo;
+       int i, len;
+       unsigned char lo;
 
        outb(0, dev->iobase + PCL818_FI_INTCLR);        /*  clear fifo int request */
 
@@ -806,8 +800,9 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
                devpriv->neverending_ai = 1;    /* well, user want neverending */
 
        if (mode == 1) {
-               i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
+               i8253_cascade_ns_to_timer(devpriv->i8253_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg,
                                          TRIG_ROUND_NEAREST);
                if (divisor1 == 1) {    /* PCL718/818 crash if any divisor is set to 1 */
                        divisor1 = 2;
@@ -1040,9 +1035,9 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 
        if (cmd->convert_src == TRIG_TIMER) {
                tmp = cmd->convert_arg;
-               i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
-                                         &divisor2, &cmd->convert_arg,
-                                         cmd->flags & TRIG_ROUND_MASK);
+               i8253_cascade_ns_to_timer(devpriv->i8253_osc_base,
+                                         &divisor1, &divisor2,
+                                         &cmd->convert_arg, cmd->flags);
                if (cmd->convert_arg < board->ns_min)
                        cmd->convert_arg = board->ns_min;
                if (tmp != cmd->convert_arg)
@@ -1077,7 +1072,6 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        devpriv->ai_chanlist = cmd->chanlist;
        devpriv->ai_flags = cmd->flags;
        devpriv->ai_data_len = s->async->prealloc_bufsz;
-       devpriv->ai_data = s->async->prealloc_buf;
        devpriv->ai_timer1 = 0;
        devpriv->ai_timer2 = 0;
 
@@ -1438,9 +1432,9 @@ no_dma:
 
        /* select 1/10MHz oscilator */
        if ((it->options[3] == 0) || (it->options[3] == 10))
-               devpriv->i8253_osc_base = 100;
+               devpriv->i8253_osc_base = I8254_OSC_BASE_10MHZ;
        else
-               devpriv->i8253_osc_base = 1000;
+               devpriv->i8253_osc_base = I8254_OSC_BASE_1MHZ;
 
        /* max sampling speed */
        devpriv->ns_min = board->ns_min;
index 423f23676d26cc1df6b8d91bf81a4691c9d0150d..fe482fdd512ed32f94af0987b236b2da28d62a57 100644 (file)
@@ -75,12 +75,6 @@ static int pcmad_ai_wait_for_eoc(struct comedi_device *dev,
        return -ETIME;
 }
 
-static bool pcmad_range_is_bipolar(struct comedi_subdevice *s,
-                                  unsigned int range)
-{
-       return s->range_table->range[range].min < 0;
-}
-
 static int pcmad_ai_insn_read(struct comedi_device *dev,
                              struct comedi_subdevice *s,
                              struct comedi_insn *insn,
@@ -106,7 +100,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev,
                if (s->maxdata == 0x0fff)
                        val >>= 4;
 
-               if (pcmad_range_is_bipolar(s, range)) {
+               if (comedi_range_is_bipolar(s, range)) {
                        /* munge the two's complement value */
                        val ^= ((s->maxdata + 1) >> 1);
                }
index 574443df42dab212d5083e7aee5affd3493ffcd9..14cee3ac92c52f67fadd05b4b3cec4d92efaec7a 100644 (file)
@@ -553,12 +553,11 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
                                                                                val |= (1U << n);
                                                                }
                                                                /* Write the scan to the buffer. */
-                                                               if (comedi_buf_put(s->async, ((short *)&val)[0])
+                                                               if (comedi_buf_put(s->async, val)
                                                                    &&
                                                                    comedi_buf_put
                                                                    (s->async,
-                                                                    ((short *)
-                                                                     &val)[1])) {
+                                                                    val >> 16)) {
                                                                        s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
                                                                } else {
                                                                        /* Overflow! Stop acquisition!! */
@@ -846,7 +845,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
                    CR_RANGE(insn->chanspec), aref = CR_AREF(insn->chanspec);
                unsigned char command_byte = 0;
                unsigned iooffset = 0;
-               short sample, adc_adjust = 0;
+               unsigned short sample, adc_adjust = 0;
 
                if (chan > 7)
                        chan -= 8, iooffset = 4;        /*
index 67e2bb1d66f00c61357780d7e95fa86d8275530d..954fa96a50ac766df3ed8d257704e46442302293 100644 (file)
@@ -315,8 +315,8 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev,
        }
 
        /* Write the scan to the buffer. */
-       if (comedi_buf_put(s->async, ((short *)&val)[0]) &&
-           comedi_buf_put(s->async, ((short *)&val)[1])) {
+       if (comedi_buf_put(s->async, val) &&
+           comedi_buf_put(s->async, val >> 16)) {
                s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
        } else {
                /* Overflow! Stop acquisition!! */
index 9775d3622a6266a51da709d951dbb6ae60e415d1..96a46954b3c09819184474a82615962a9120146d 100644 (file)
@@ -208,8 +208,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id)
        case buffer:
                while (!((status = inb(dev->iobase + DAQP_STATUS))
                         & DAQP_STATUS_FIFO_EMPTY)) {
-
-                       short data;
+                       unsigned short data;
 
                        if (status & DAQP_STATUS_DATA_LOST) {
                                s->async->events |=
@@ -690,18 +689,12 @@ static int daqp_do_insn_bits(struct comedi_device *dev,
                             unsigned int *data)
 {
        struct daqp_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
 
        if (devpriv->stop)
                return -EIO;
 
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data))
                outb(s->state, dev->iobase + DAQP_DIGITAL_IO);
-       }
 
        data[1] = s->state;
 
index 93c980c62a23a96ded07673231cf216e85055f2e..44c8712ed9e05ddf939f1792dd452b94d2e7044f 100644 (file)
@@ -394,11 +394,8 @@ struct rtd_private {
        long ai_count;          /* total transfer size (samples) */
        int xfer_count;         /* # to transfer data. 0->1/2FIFO */
        int flags;              /* flag event modes */
-
-       unsigned char chan_is_bipolar[RTD_MAX_CHANLIST / 8];    /* bit array */
-
+       DECLARE_BITMAP(chan_is_bipolar, RTD_MAX_CHANLIST);
        unsigned int ao_readback[2];
-
        unsigned fifosz;
 };
 
@@ -407,14 +404,6 @@ struct rtd_private {
 #define DMA0_ACTIVE    0x02    /* DMA0 is active */
 #define DMA1_ACTIVE    0x04    /* DMA1 is active */
 
-/* Macros for accessing channel list bit array */
-#define CHAN_ARRAY_TEST(array, index) \
-       (((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
-#define CHAN_ARRAY_SET(array, index) \
-       (((array)[(index)/8] |= 1 << ((index) & 0x7)))
-#define CHAN_ARRAY_CLEAR(array, index) \
-       (((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
-
 /*
   Given a desired period and the clock period (both in ns),
   return the proper counter value (divider-1).
@@ -478,17 +467,17 @@ static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
                /* +-5 range */
                r |= 0x000;
                r |= (range & 0x7) << 4;
-               CHAN_ARRAY_SET(devpriv->chan_is_bipolar, index);
+               __set_bit(index, devpriv->chan_is_bipolar);
        } else if (range < board->range_uni10) {
                /* +-10 range */
                r |= 0x100;
                r |= ((range - board->range_bip10) & 0x7) << 4;
-               CHAN_ARRAY_SET(devpriv->chan_is_bipolar, index);
+               __set_bit(index, devpriv->chan_is_bipolar);
        } else {
                /* +10 range */
                r |= 0x200;
                r |= ((range - board->range_uni10) & 0x7) << 4;
-               CHAN_ARRAY_CLEAR(devpriv->chan_is_bipolar, index);
+               __clear_bit(index, devpriv->chan_is_bipolar);
        }
 
        switch (aref) {
@@ -602,7 +591,7 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
 
        /* convert n samples */
        for (n = 0; n < insn->n; n++) {
-               s16 d;
+               unsigned short d;
                /* trigger conversion */
                writew(0, devpriv->las0 + LAS0_ADC);
 
@@ -619,11 +608,10 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
                d = readw(devpriv->las1 + LAS1_ADC_FIFO);
                /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */
                d = d >> 3;     /* low 3 bits are marker lines */
-               if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar, 0))
+               if (test_bit(0, devpriv->chan_is_bipolar))
                        /* convert to comedi unsigned data */
-                       data[n] = d + 2048;
-               else
-                       data[n] = d;
+                       d = comedi_offset_munge(s, d);
+               data[n] = d & s->maxdata;
        }
 
        /* return the number of samples read/written */
@@ -643,8 +631,7 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
        int ii;
 
        for (ii = 0; ii < count; ii++) {
-               short sample;
-               s16 d;
+               unsigned short d;
 
                if (0 == devpriv->ai_count) {   /* done */
                        d = readw(devpriv->las1 + LAS1_ADC_FIFO);
@@ -653,14 +640,12 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
 
                d = readw(devpriv->las1 + LAS1_ADC_FIFO);
                d = d >> 3;     /* low 3 bits are marker lines */
-               if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar,
-                                   s->async->cur_chan)) {
+               if (test_bit(s->async->cur_chan, devpriv->chan_is_bipolar))
                        /* convert to comedi unsigned data */
-                       sample = d + 2048;
-               } else
-                       sample = d;
+                       d = comedi_offset_munge(s, d);
+               d &= s->maxdata;
 
-               if (!comedi_buf_put(s->async, sample))
+               if (!comedi_buf_put(s->async, d))
                        return -1;
 
                if (devpriv->ai_count > 0)      /* < 0, means read forever */
@@ -677,22 +662,19 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
        struct rtd_private *devpriv = dev->private;
 
        while (readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
-               short sample;
-               s16 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
+               unsigned short d = readw(devpriv->las1 + LAS1_ADC_FIFO);
 
                if (0 == devpriv->ai_count) {   /* done */
                        continue;       /* read rest */
                }
 
                d = d >> 3;     /* low 3 bits are marker lines */
-               if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar,
-                                   s->async->cur_chan)) {
+               if (test_bit(s->async->cur_chan, devpriv->chan_is_bipolar))
                        /* convert to comedi unsigned data */
-                       sample = d + 2048;
-               } else
-                       sample = d;
+                       d = comedi_offset_munge(s, d);
+               d &= s->maxdata;
 
-               if (!comedi_buf_put(s->async, sample))
+               if (!comedi_buf_put(s->async, d))
                        return -1;
 
                if (devpriv->ai_count > 0)      /* < 0, means read forever */
@@ -1217,15 +1199,9 @@ static int rtd_dio_insn_bits(struct comedi_device *dev,
                             unsigned int *data)
 {
        struct rtd_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_update_state(s, data))
                writew(s->state & 0xff, devpriv->las0 + LAS0_DIO0);
-       }
 
        data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
 
index cbb4ba5b852a1fdf43b44a0c2b7dacd2092f8c60..e1f3671ac056095982922ff3697832f9ded54dbf 100644 (file)
@@ -267,13 +267,7 @@ static int rti800_do_insn_bits(struct comedi_device *dev,
                               struct comedi_insn *insn,
                               unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_update_state(s, data)) {
                /* Outputs are inverted... */
                outb(s->state ^ 0xff, dev->iobase + RTI800_DO);
        }
index d629463b85a2ae38ba7c97d8329633ce606b7c1c..9950f59b1192c99dc471265027dbb2a9fd26fc4a 100644 (file)
@@ -499,14 +499,11 @@ static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 
 static int s526_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-
+       if (comedi_dio_update_state(s, data))
                outw(s->state, dev->iobase + REG_DIO);
-       }
 
        data[1] = inw(dev->iobase + REG_DIO) & 0xff;
 
index d22b95dcb9bdff2ae4e064513ac7295f16b7fbbf..92062ed0ac20cce27c8a11fa093e3bd4a99c1f5e 100644 (file)
@@ -1,63 +1,63 @@
 /*
-  comedi/drivers/s626.c
-  Sensoray s626 Comedi driver
-
-  COMEDI - Linux Control and Measurement Device Interface
-  Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
-  Based on Sensoray Model 626 Linux driver Version 0.2
-  Copyright (C) 2002-2004 Sensoray Co., Inc.
-
-  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.
-*/
* comedi/drivers/s626.c
* Sensoray s626 Comedi driver
+ *
* COMEDI - Linux Control and Measurement Device Interface
* Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
* Based on Sensoray Model 626 Linux driver Version 0.2
* Copyright (C) 2002-2004 Sensoray Co., Inc.
+ *
* 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.
+ */
 
 /*
-Driver: s626
-Description: Sensoray 626 driver
-Devices: [Sensoray] 626 (s626)
-Authors: Gianluca Palli <gpalli@deis.unibo.it>,
-Updated: Fri, 15 Feb 2008 10:28:42 +0000
-Status: experimental
-
-Configuration options: not applicable, uses PCI auto config
-
-INSN_CONFIG instructions:
-  analog input:
-   none
-
-  analog output:
-   none
-
-  digital channel:
-   s626 has 3 dio subdevices (2,3 and 4) each with 16 i/o channels
-   supported configuration options:
-   INSN_CONFIG_DIO_QUERY
-   COMEDI_INPUT
-   COMEDI_OUTPUT
-
-  encoder:
-   Every channel must be configured before reading.
-
-   Example code
-
-   insn.insn=INSN_CONFIG;   //configuration instruction
-   insn.n=1;                //number of operation (must be 1)
-   insn.data=&initialvalue; //initial value loaded into encoder
                              //during configuration
-   insn.subdev=5;           //encoder subdevice
-   insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel
-                                                       //to configure
-
-   comedi_do_insn(cf,&insn); //executing configuration
-*/
+ * Driver: s626
+ * Description: Sensoray 626 driver
+ * Devices: [Sensoray] 626 (s626)
+ * Authors: Gianluca Palli <gpalli@deis.unibo.it>,
+ * Updated: Fri, 15 Feb 2008 10:28:42 +0000
+ * Status: experimental
+
+ * Configuration options: not applicable, uses PCI auto config
+
+ * INSN_CONFIG instructions:
*   analog input:
*    none
+ *
*   analog output:
*    none
+ *
*   digital channel:
*    s626 has 3 dio subdevices (2,3 and 4) each with 16 i/o channels
*    supported configuration options:
*    INSN_CONFIG_DIO_QUERY
*    COMEDI_INPUT
*    COMEDI_OUTPUT
+ *
*   encoder:
*    Every channel must be configured before reading.
+ *
  Example code
+ *
*    insn.insn=INSN_CONFIG;   //configuration instruction
*    insn.n=1;                //number of operation (must be 1)
*    insn.data=&initialvalue; //initial value loaded into encoder
*                             //during configuration
*    insn.subdev=5;           //encoder subdevice
*    insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel
*                                                         //to configure
+ *
*    comedi_do_insn(cf,&insn); //executing configuration
+ */
 
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -71,68 +71,91 @@ INSN_CONFIG instructions:
 #include "comedi_fc.h"
 #include "s626.h"
 
-#define PCI_VENDOR_ID_S626 0x1131
-#define PCI_DEVICE_ID_S626 0x7146
-#define PCI_SUBVENDOR_ID_S626 0x6000
-#define PCI_SUBDEVICE_ID_S626 0x0272
+struct s626_buffer_dma {
+       dma_addr_t physical_base;
+       void *logical_base;
+};
 
 struct s626_private {
        void __iomem *mmio;
-       uint8_t ai_cmd_running; /*  ai_cmd is running */
-       uint8_t ai_continous;   /*  continous acquisition */
-       int ai_sample_count;    /*  number of samples to acquire */
-       unsigned int ai_sample_timer;
-       /*  time between samples in  units of the timer */
-       int ai_convert_count;   /*  conversion counter */
-       unsigned int ai_convert_timer;
-       /*  time between conversion in  units of the timer */
-       uint16_t CounterIntEnabs;
-       /* Counter interrupt enable  mask for MISC2 register. */
-       uint8_t AdcItems;       /* Number of items in ADC poll  list. */
-       struct bufferDMA RPSBuf;        /* DMA buffer used to hold ADC (RPS1) program. */
-       struct bufferDMA ANABuf;
-       /* DMA buffer used to receive ADC data and hold DAC data. */
-       uint32_t *pDacWBuf;
-       /* Pointer to logical adrs of DMA buffer used to hold DAC  data. */
-       uint16_t Dacpol;        /* Image of DAC polarity register. */
-       uint8_t TrimSetpoint[12];       /* Images of TrimDAC setpoints */
-       /* Charge Enabled (0 or WRMISC2_CHARGE_ENABLE). */
-       uint32_t I2CAdrs;
-       /* I2C device address for onboard EEPROM (board rev dependent). */
-       /*   short         I2Cards; */
+       uint8_t ai_cmd_running;         /* ai_cmd is running */
+       uint8_t ai_continuous;          /* continuous acquisition */
+       int ai_sample_count;            /* number of samples to acquire */
+       unsigned int ai_sample_timer;   /* time between samples in
+                                        * units of the timer */
+       int ai_convert_count;           /* conversion counter */
+       unsigned int ai_convert_timer;  /* time between conversion in
+                                        * units of the timer */
+       uint16_t counter_int_enabs;     /* counter interrupt enable mask
+                                        * for MISC2 register */
+       uint8_t adc_items;              /* number of items in ADC poll list */
+       struct s626_buffer_dma rps_buf; /* DMA buffer used to hold ADC (RPS1)
+                                        * program */
+       struct s626_buffer_dma ana_buf; /* DMA buffer used to receive ADC data
+                                        * and hold DAC data */
+       uint32_t *dac_wbuf;             /* pointer to logical adrs of DMA buffer
+                                        * used to hold DAC data */
+       uint16_t dacpol;                /* image of DAC polarity register */
+       uint8_t trim_setpoint[12];      /* images of TrimDAC setpoints */
+       uint32_t i2c_adrs;              /* I2C device address for onboard EEPROM
+                                        * (board rev dependent) */
        unsigned int ao_readback[S626_DAC_CHANNELS];
 };
 
-/*  COUNTER OBJECT ------------------------------------------------ */
-struct enc_private {
-       /*  Pointers to functions that differ for A and B counters: */
-       uint16_t(*GetEnable) (struct comedi_device *dev, struct enc_private *); /* Return clock enable. */
-       uint16_t(*GetIntSrc) (struct comedi_device *dev, struct enc_private *); /* Return interrupt source. */
-       uint16_t(*GetLoadTrig) (struct comedi_device *dev, struct enc_private *);       /* Return preload trigger source. */
-       uint16_t(*GetMode) (struct comedi_device *dev, struct enc_private *);   /* Return standardized operating mode. */
-       void (*PulseIndex) (struct comedi_device *dev, struct enc_private *);   /* Generate soft index strobe. */
-       void (*SetEnable) (struct comedi_device *dev, struct enc_private *, uint16_t enab);     /* Program clock enable. */
-       void (*SetIntSrc) (struct comedi_device *dev, struct enc_private *, uint16_t IntSource);        /* Program interrupt source. */
-       void (*SetLoadTrig) (struct comedi_device *dev, struct enc_private *, uint16_t Trig);   /* Program preload trigger source. */
-       void (*SetMode) (struct comedi_device *dev, struct enc_private *, uint16_t Setup, uint16_t DisableIntSrc);      /* Program standardized operating mode. */
-       void (*ResetCapFlags) (struct comedi_device *dev, struct enc_private *);        /* Reset event capture flags. */
-
-       uint16_t MyCRA;         /*    Address of CRA register. */
-       uint16_t MyCRB;         /*    Address of CRB register. */
-       uint16_t MyLatchLsw;    /*    Address of Latch least-significant-word */
-       /*    register. */
-       uint16_t MyEventBits[4];        /*    Bit translations for IntSrc -->RDMISC2. */
+/* COUNTER OBJECT ------------------------------------------------ */
+struct s626_enc_info {
+       /* Pointers to functions that differ for A and B counters: */
+       /* Return clock enable. */
+       uint16_t(*get_enable)(struct comedi_device *dev,
+                             const struct s626_enc_info *k);
+       /* Return interrupt source. */
+       uint16_t(*get_int_src)(struct comedi_device *dev,
+                              const struct s626_enc_info *k);
+       /* Return preload trigger source. */
+       uint16_t(*get_load_trig)(struct comedi_device *dev,
+                                const struct s626_enc_info *k);
+       /* Return standardized operating mode. */
+       uint16_t(*get_mode)(struct comedi_device *dev,
+                           const struct s626_enc_info *k);
+       /* Generate soft index strobe. */
+       void (*pulse_index)(struct comedi_device *dev,
+                           const struct s626_enc_info *k);
+       /* Program clock enable. */
+       void (*set_enable)(struct comedi_device *dev,
+                          const struct s626_enc_info *k, uint16_t enab);
+       /* Program interrupt source. */
+       void (*set_int_src)(struct comedi_device *dev,
+                           const struct s626_enc_info *k, uint16_t int_source);
+       /* Program preload trigger source. */
+       void (*set_load_trig)(struct comedi_device *dev,
+                             const struct s626_enc_info *k, uint16_t trig);
+       /* Program standardized operating mode. */
+       void (*set_mode)(struct comedi_device *dev,
+                        const struct s626_enc_info *k, uint16_t setup,
+                        uint16_t disable_int_src);
+       /* Reset event capture flags. */
+       void (*reset_cap_flags)(struct comedi_device *dev,
+                               const struct s626_enc_info *k);
+
+       uint16_t my_cra;        /* address of CRA register */
+       uint16_t my_crb;        /* address of CRB register */
+       uint16_t my_latch_lsw;  /* address of Latch least-significant-word
+                                * register */
+       uint16_t my_event_bits[4]; /* bit translations for IntSrc -->RDMISC2 */
 };
 
-#define encpriv ((struct enc_private *)(dev->subdevices+5)->private)
-
-/*  Counter overflow/index event flag masks for RDMISC2. */
-#define INDXMASK(C)            (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 +  4)))
-#define OVERMASK(C)            (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
-#define EVBITS(C)              { 0, OVERMASK(C), INDXMASK(C), OVERMASK(C) | INDXMASK(C) }
+/* Counter overflow/index event flag masks for RDMISC2. */
+#define S626_INDXMASK(C) (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 +  4)))
+#define S626_OVERMASK(C) (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
+#define S626_EVBITS(C) { 0, S626_OVERMASK(C), S626_INDXMASK(C), \
+                         S626_OVERMASK(C) | S626_INDXMASK(C) }
 
-/*  Translation table to map IntSrc into equivalent RDMISC2 event flag  bits. */
-/* static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) }; */
+/*
+ * Translation table to map IntSrc into equivalent RDMISC2 event flag  bits.
+ * static const uint16_t s626_event_bits[][4] =
+ *     { S626_EVBITS(0), S626_EVBITS(1), S626_EVBITS(2), S626_EVBITS(3),
+ *       S626_EVBITS(4), S626_EVBITS(5) };
+ */
 
 /*
  * Enable/disable a function or test status bit(s) that are accessed
@@ -144,6 +167,7 @@ static void s626_mc_enable(struct comedi_device *dev,
        struct s626_private *devpriv = dev->private;
        unsigned int val = (cmd << 16) | cmd;
 
+       mmiowb();
        writel(val, devpriv->mmio + reg);
 }
 
@@ -153,6 +177,7 @@ static void s626_mc_disable(struct comedi_device *dev,
        struct s626_private *devpriv = dev->private;
 
        writel(cmd << 16 , devpriv->mmio + reg);
+       mmiowb();
 }
 
 static bool s626_mc_test(struct comedi_device *dev,
@@ -166,15 +191,10 @@ static bool s626_mc_test(struct comedi_device *dev,
        return (val & cmd) ? true : false;
 }
 
-#define BUGFIX_STREG(REGADRS)   (REGADRS - 4)
+#define S626_BUGFIX_STREG(REGADRS)   ((REGADRS) - 4)
 
-/*  Write a time slot control record to TSL2. */
-#define VECTPORT(VECTNUM)              (P_TSL2 + ((VECTNUM) << 2))
-
-/*  Code macros used for constructing I2C command bytes. */
-#define I2C_B2(ATTR, VAL)      (((ATTR) << 6) | ((VAL) << 24))
-#define I2C_B1(ATTR, VAL)      (((ATTR) << 4) | ((VAL) << 16))
-#define I2C_B0(ATTR, VAL)      (((ATTR) << 2) | ((VAL) <<  8))
+/* Write a time slot control record to TSL2. */
+#define S626_VECTPORT(VECTNUM)         (S626_P_TSL2 + ((VECTNUM) << 2))
 
 static const struct comedi_lrange s626_range_table = {
        2, {
@@ -183,178 +203,182 @@ static const struct comedi_lrange s626_range_table = {
        }
 };
 
-/*  Execute a DEBI transfer.  This must be called from within a */
-/*  critical section. */
-static void DEBItransfer(struct comedi_device *dev)
+/*
+ * Execute a DEBI transfer.  This must be called from within a critical section.
+ */
+static void s626_debi_transfer(struct comedi_device *dev)
 {
        struct s626_private *devpriv = dev->private;
 
        /* Initiate upload of shadow RAM to DEBI control register */
-       s626_mc_enable(dev, MC2_UPLD_DEBI, P_MC2);
+       s626_mc_enable(dev, S626_MC2_UPLD_DEBI, S626_P_MC2);
 
        /*
         * Wait for completion of upload from shadow RAM to
         * DEBI control register.
         */
-       while (!s626_mc_test(dev, MC2_UPLD_DEBI, P_MC2))
+       while (!s626_mc_test(dev, S626_MC2_UPLD_DEBI, S626_P_MC2))
                ;
 
        /* Wait until DEBI transfer is done */
-       while (readl(devpriv->mmio + P_PSR) & PSR_DEBI_S)
+       while (readl(devpriv->mmio + S626_P_PSR) & S626_PSR_DEBI_S)
                ;
 }
 
-/*  Initialize the DEBI interface for all transfers. */
-
-static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr)
+/*
+ * Read a value from a gate array register.
+ */
+static uint16_t s626_debi_read(struct comedi_device *dev, uint16_t addr)
 {
        struct s626_private *devpriv = dev->private;
 
        /* Set up DEBI control register value in shadow RAM */
-       writel(DEBI_CMD_RDWORD | addr, devpriv->mmio + P_DEBICMD);
+       writel(S626_DEBI_CMD_RDWORD | addr, devpriv->mmio + S626_P_DEBICMD);
 
        /*  Execute the DEBI transfer. */
-       DEBItransfer(dev);
+       s626_debi_transfer(dev);
 
-       return readl(devpriv->mmio + P_DEBIAD);
+       return readl(devpriv->mmio + S626_P_DEBIAD);
 }
 
-/*  Write a value to a gate array register. */
-static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
+/*
+ * Write a value to a gate array register.
+ */
+static void s626_debi_write(struct comedi_device *dev, uint16_t addr,
+                           uint16_t wdata)
 {
        struct s626_private *devpriv = dev->private;
 
        /* Set up DEBI control register value in shadow RAM */
-       writel(DEBI_CMD_WRWORD | addr, devpriv->mmio + P_DEBICMD);
-       writel(wdata, devpriv->mmio + P_DEBIAD);
+       writel(S626_DEBI_CMD_WRWORD | addr, devpriv->mmio + S626_P_DEBICMD);
+       writel(wdata, devpriv->mmio + S626_P_DEBIAD);
 
        /*  Execute the DEBI transfer. */
-       DEBItransfer(dev);
+       s626_debi_transfer(dev);
 }
 
-/* Replace the specified bits in a gate array register.  Imports: mask
+/*
+ * Replace the specified bits in a gate array register.  Imports: mask
  * specifies bits that are to be preserved, wdata is new value to be
  * or'd with the masked original.
  */
-static void DEBIreplace(struct comedi_device *dev, unsigned int addr,
-                       unsigned int mask, unsigned int wdata)
+static void s626_debi_replace(struct comedi_device *dev, unsigned int addr,
+                             unsigned int mask, unsigned int wdata)
 {
        struct s626_private *devpriv = dev->private;
        unsigned int val;
 
        addr &= 0xffff;
-       writel(DEBI_CMD_RDWORD | addr, devpriv->mmio + P_DEBICMD);
-       DEBItransfer(dev);
+       writel(S626_DEBI_CMD_RDWORD | addr, devpriv->mmio + S626_P_DEBICMD);
+       s626_debi_transfer(dev);
 
-       writel(DEBI_CMD_WRWORD | addr, devpriv->mmio + P_DEBICMD);
-       val = readl(devpriv->mmio + P_DEBIAD);
+       writel(S626_DEBI_CMD_WRWORD | addr, devpriv->mmio + S626_P_DEBICMD);
+       val = readl(devpriv->mmio + S626_P_DEBIAD);
        val &= mask;
        val |= wdata;
-       writel(val & 0xffff, devpriv->mmio + P_DEBIAD);
-       DEBItransfer(dev);
+       writel(val & 0xffff, devpriv->mmio + S626_P_DEBIAD);
+       s626_debi_transfer(dev);
 }
 
 /* **************  EEPROM ACCESS FUNCTIONS  ************** */
 
-static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
+static uint32_t s626_i2c_handshake(struct comedi_device *dev, uint32_t val)
 {
        struct s626_private *devpriv = dev->private;
        unsigned int ctrl;
 
        /* Write I2C command to I2C Transfer Control shadow register */
-       writel(val, devpriv->mmio + P_I2CCTRL);
+       writel(val, devpriv->mmio + S626_P_I2CCTRL);
 
        /*
         * Upload I2C shadow registers into working registers and
         * wait for upload confirmation.
         */
-       s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2);
-       while (!s626_mc_test(dev, MC2_UPLD_IIC, P_MC2))
+       s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
+       while (!s626_mc_test(dev, S626_MC2_UPLD_IIC, S626_P_MC2))
                ;
 
        /* Wait until I2C bus transfer is finished or an error occurs */
        do {
-               ctrl = readl(devpriv->mmio + P_I2CCTRL);
-       } while ((ctrl & (I2C_BUSY | I2C_ERR)) == I2C_BUSY);
+               ctrl = readl(devpriv->mmio + S626_P_I2CCTRL);
+       } while ((ctrl & (S626_I2C_BUSY | S626_I2C_ERR)) == S626_I2C_BUSY);
 
        /* Return non-zero if I2C error occurred */
-       return ctrl & I2C_ERR;
+       return ctrl & S626_I2C_ERR;
 }
 
-/*  Read uint8_t from EEPROM. */
-static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
+/* Read uint8_t from EEPROM. */
+static uint8_t s626_i2c_read(struct comedi_device *dev, uint8_t addr)
 {
        struct s626_private *devpriv = dev->private;
 
-       /*  Send EEPROM target address. */
-       if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW)
-                        /* Byte2 = I2C command: write to I2C EEPROM  device. */
-                        | I2C_B1(I2C_ATTRSTOP, addr)
-                        /* Byte1 = EEPROM internal target address. */
-                        | I2C_B0(I2C_ATTRNOP, 0))) {   /*  Byte0 = Not sent. */
-               /*  Abort function and declare error if handshake failed. */
+       /*
+        * Send EEPROM target address:
+        *  Byte2 = I2C command: write to I2C EEPROM device.
+        *  Byte1 = EEPROM internal target address.
+        *  Byte0 = Not sent.
+        */
+       if (s626_i2c_handshake(dev, S626_I2C_B2(S626_I2C_ATTRSTART,
+                                               devpriv->i2c_adrs) |
+                                   S626_I2C_B1(S626_I2C_ATTRSTOP, addr) |
+                                   S626_I2C_B0(S626_I2C_ATTRNOP, 0)))
+               /* Abort function and declare error if handshake failed. */
                return 0;
-       }
-       /*  Execute EEPROM read. */
-       if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR)
-
-                        /*  Byte2 = I2C */
-                        /*  command: read */
-                        /*  from I2C EEPROM */
-                        /*  device. */
-                        |I2C_B1(I2C_ATTRSTOP, 0)
 
-                        /*  Byte1 receives */
-                        /*  uint8_t from */
-                        /*  EEPROM. */
-                        |I2C_B0(I2C_ATTRNOP, 0))) {    /*  Byte0 = Not  sent. */
-
-               /*  Abort function and declare error if handshake failed. */
+       /*
+        * Execute EEPROM read:
+        *  Byte2 = I2C command: read from I2C EEPROM device.
+        *  Byte1 receives uint8_t from EEPROM.
+        *  Byte0 = Not sent.
+        */
+       if (s626_i2c_handshake(dev, S626_I2C_B2(S626_I2C_ATTRSTART,
+                                          (devpriv->i2c_adrs | 1)) |
+                                   S626_I2C_B1(S626_I2C_ATTRSTOP, 0) |
+                                   S626_I2C_B0(S626_I2C_ATTRNOP, 0)))
+               /* Abort function and declare error if handshake failed. */
                return 0;
-       }
 
-       return (readl(devpriv->mmio + P_I2CCTRL) >> 16) & 0xff;
+       return (readl(devpriv->mmio + S626_P_I2CCTRL) >> 16) & 0xff;
 }
 
 /* ***********  DAC FUNCTIONS *********** */
 
-/*  Slot 0 base settings. */
-#define VECT0  (XSD2 | RSD3 | SIB_A2)
-/*  Slot 0 always shifts in  0xFF and store it to  FB_BUFFER2. */
+/* TrimDac LogicalChan-to-PhysicalChan mapping table. */
+static const uint8_t s626_trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
 
-/*  TrimDac LogicalChan-to-PhysicalChan mapping table. */
-static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
-
-/*  TrimDac LogicalChan-to-EepromAdrs mapping table. */
-static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
+/* TrimDac LogicalChan-to-EepromAdrs mapping table. */
+static const uint8_t s626_trimadrs[] = {
+       0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63
+};
 
-/* Private helper function: Transmit serial data to DAC via Audio
+/*
+ * Private helper function: Transmit serial data to DAC via Audio
  * channel 2.  Assumes: (1) TSL2 slot records initialized, and (2)
- * Dacpol contains valid target image.
+ * dacpol contains valid target image.
  */
-static void SendDAC(struct comedi_device *dev, uint32_t val)
+static void s626_send_dac(struct comedi_device *dev, uint32_t val)
 {
        struct s626_private *devpriv = dev->private;
 
        /* START THE SERIAL CLOCK RUNNING ------------- */
 
-       /* Assert DAC polarity control and enable gating of DAC serial clock
+       /*
+        * Assert DAC polarity control and enable gating of DAC serial clock
         * and audio bit stream signals.  At this point in time we must be
         * assured of being in time slot 0.  If we are not in slot 0, the
         * serial clock and audio stream signals will be disabled; this is
-        * because the following DEBIwrite statement (which enables signals
-        * to be passed through the gate array) would execute before the
-        * trailing edge of WS1/WS3 (which turns off the signals), thus
+        * because the following s626_debi_write statement (which enables
+        * signals to be passed through the gate array) would execute before
+        * the trailing edge of WS1/WS3 (which turns off the signals), thus
         * causing the signals to be inactive during the DAC write.
         */
-       DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol);
+       s626_debi_write(dev, S626_LP_DACPOL, devpriv->dacpol);
 
        /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */
 
        /* Copy DAC setpoint value to DAC's output DMA buffer. */
-
-       /* writel(val, devpriv->mmio + (uint32_t)devpriv->pDacWBuf); */
-       *devpriv->pDacWBuf = val;
+       /* writel(val, devpriv->mmio + (uint32_t)devpriv->dac_wbuf); */
+       *devpriv->dac_wbuf = val;
 
        /*
         * Enable the output DMA transfer. This will cause the DMAC to copy
@@ -362,56 +386,62 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
         * then immediately terminate because the protection address is
         * reached upon transfer of the first DWORD value.
         */
-       s626_mc_enable(dev, MC1_A2OUT, P_MC1);
+       s626_mc_enable(dev, S626_MC1_A2OUT, S626_P_MC1);
 
-       /*  While the DMA transfer is executing ... */
+       /* While the DMA transfer is executing ... */
 
        /*
         * Reset Audio2 output FIFO's underflow flag (along with any
         * other FIFO underflow/overflow flags). When set, this flag
         * will indicate that we have emerged from slot 0.
         */
-       writel(ISR_AFOU, devpriv->mmio + P_ISR);
+       writel(S626_ISR_AFOU, devpriv->mmio + S626_P_ISR);
 
-       /* Wait for the DMA transfer to finish so that there will be data
+       /*
+        * Wait for the DMA transfer to finish so that there will be data
         * available in the FIFO when time slot 1 tries to transfer a DWORD
         * from the FIFO to the output buffer register.  We test for DMA
         * Done by polling the DMAC enable flag; this flag is automatically
         * cleared when the transfer has finished.
         */
-       while (readl(devpriv->mmio + P_MC1) & MC1_A2OUT)
+       while (readl(devpriv->mmio + S626_P_MC1) & S626_MC1_A2OUT)
                ;
 
        /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */
 
-       /* FIFO data is now available, so we enable execution of time slots
+       /*
+        * FIFO data is now available, so we enable execution of time slots
         * 1 and higher by clearing the EOS flag in slot 0.  Note that SD3
         * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
         * detection.
         */
-       writel(XSD2 | RSD3 | SIB_A2, devpriv->mmio + VECTPORT(0));
+       writel(S626_XSD2 | S626_RSD3 | S626_SIB_A2,
+              devpriv->mmio + S626_VECTPORT(0));
 
-       /* Wait for slot 1 to execute to ensure that the Packet will be
+       /*
+        * Wait for slot 1 to execute to ensure that the Packet will be
         * transmitted.  This is detected by polling the Audio2 output FIFO
         * underflow flag, which will be set when slot 1 execution has
         * finished transferring the DAC's data DWORD from the output FIFO
         * to the output buffer register.
         */
-       while (!(readl(devpriv->mmio + P_SSR) & SSR_AF2_OUT))
+       while (!(readl(devpriv->mmio + S626_P_SSR) & S626_SSR_AF2_OUT))
                ;
 
-       /* Set up to trap execution at slot 0 when the TSL sequencer cycles
+       /*
+        * Set up to trap execution at slot 0 when the TSL sequencer cycles
         * back to slot 0 after executing the EOS in slot 5.  Also,
         * simultaneously shift out and in the 0x00 that is ALWAYS the value
         * stored in the last byte to be shifted out of the FIFO's DWORD
         * buffer register.
         */
-       writel(XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS,
-              devpriv->mmio + VECTPORT(0));
+       writel(S626_XSD2 | S626_XFIFO_2 | S626_RSD2 | S626_SIB_A2 | S626_EOS,
+              devpriv->mmio + S626_VECTPORT(0));
 
        /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */
 
-       /* Wait for the TSL to finish executing all time slots before
+       /*
+        * Wait for the TSL to finish executing all time slots before
         * exiting this function.  We must do this so that the next DAC
         * write doesn't start, thereby enabling clock/chip select signals:
         *
@@ -428,17 +458,19 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
         *    we test for the FB_BUFFER2 MSB contents to be equal to 0xFF.  If
         *    the TSL has not yet finished executing slot 5 ...
         */
-       if (readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000) {
-               /* The trap was set on time and we are still executing somewhere
+       if (readl(devpriv->mmio + S626_P_FB_BUFFER2) & 0xff000000) {
+               /*
+                * The trap was set on time and we are still executing somewhere
                 * in slots 2-5, so we now wait for slot 0 to execute and trap
                 * TSL execution.  This is detected when FB_BUFFER2 MSB changes
                 * from 0xFF to 0x00, which slot 0 causes to happen by shifting
                 * out/in on SD2 the 0x00 that is always referenced by slot 5.
                 */
-               while (readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000)
+               while (readl(devpriv->mmio + S626_P_FB_BUFFER2) & 0xff000000)
                        ;
        }
-       /* Either (1) we were too late setting the slot 0 trap; the TSL
+       /*
+        * Either (1) we were too late setting the slot 0 trap; the TSL
         * sequencer restarted slot 0 before we could set the EOS trap flag,
         * or (2) we were not late and execution is now trapped at slot 0.
         * In either case, we must now change slot 0 so that it will store
@@ -446,37 +478,46 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
         * In order to do this, we reprogram slot 0 so that it will shift in
         * SD3, which is driven only by a pull-up resistor.
         */
-       writel(RSD3 | SIB_A2 | EOS, devpriv->mmio + VECTPORT(0));
+       writel(S626_RSD3 | S626_SIB_A2 | S626_EOS,
+              devpriv->mmio + S626_VECTPORT(0));
 
-       /* Wait for slot 0 to execute, at which time the TSL is setup for
+       /*
+        * Wait for slot 0 to execute, at which time the TSL is setup for
         * the next DAC write.  This is detected when FB_BUFFER2 MSB changes
         * from 0x00 to 0xFF.
         */
-       while (!(readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000))
+       while (!(readl(devpriv->mmio + S626_P_FB_BUFFER2) & 0xff000000))
                ;
 }
 
-/*  Private helper function: Write setpoint to an application DAC channel. */
-static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
+/*
+ * Private helper function: Write setpoint to an application DAC channel.
+ */
+static void s626_set_dac(struct comedi_device *dev, uint16_t chan,
+                        unsigned short dacdata)
 {
        struct s626_private *devpriv = dev->private;
-       register uint16_t signmask;
-       register uint32_t WSImage;
+       uint16_t signmask;
+       uint32_t ws_image;
+       uint32_t val;
 
-       /*  Adjust DAC data polarity and set up Polarity Control Register */
-       /*  image. */
+       /*
+        * Adjust DAC data polarity and set up Polarity Control Register image.
+        */
        signmask = 1 << chan;
        if (dacdata < 0) {
                dacdata = -dacdata;
-               devpriv->Dacpol |= signmask;
-       } else
-               devpriv->Dacpol &= ~signmask;
+               devpriv->dacpol |= signmask;
+       } else {
+               devpriv->dacpol &= ~signmask;
+       }
 
-       /*  Limit DAC setpoint value to valid range. */
-       if ((uint16_t) dacdata > 0x1FFF)
+       /* Limit DAC setpoint value to valid range. */
+       if ((uint16_t)dacdata > 0x1FFF)
                dacdata = 0x1FFF;
 
-       /* Set up TSL2 records (aka "vectors") for DAC update.  Vectors V2
+       /*
+        * Set up TSL2 records (aka "vectors") for DAC update.  Vectors V2
         * and V3 transmit the setpoint to the target DAC.  V4 and V5 send
         * data to a non-existent TrimDac channel just to keep the clock
         * running after sending data to the target DAC.  This is necessary
@@ -487,140 +528,811 @@ static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
         */
 
        /* Choose DAC chip select to be asserted */
-       WSImage = (chan & 2) ? WS1 : WS2;
+       ws_image = (chan & 2) ? S626_WS1 : S626_WS2;
        /* Slot 2: Transmit high data byte to target DAC */
-       writel(XSD2 | XFIFO_1 | WSImage, devpriv->mmio + VECTPORT(2));
+       writel(S626_XSD2 | S626_XFIFO_1 | ws_image,
+              devpriv->mmio + S626_VECTPORT(2));
        /* Slot 3: Transmit low data byte to target DAC */
-       writel(XSD2 | XFIFO_0 | WSImage, devpriv->mmio + VECTPORT(3));
+       writel(S626_XSD2 | S626_XFIFO_0 | ws_image,
+              devpriv->mmio + S626_VECTPORT(3));
        /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */
-       writel(XSD2 | XFIFO_3 | WS3, devpriv->mmio + VECTPORT(4));
+       writel(S626_XSD2 | S626_XFIFO_3 | S626_WS3,
+              devpriv->mmio + S626_VECTPORT(4));
        /* Slot 5: running after writing target DAC's low data byte */
-       writel(XSD2 | XFIFO_2 | WS3 | EOS, devpriv->mmio + VECTPORT(5));
+       writel(S626_XSD2 | S626_XFIFO_2 | S626_WS3 | S626_EOS,
+              devpriv->mmio + S626_VECTPORT(5));
 
-       /*  Construct and transmit target DAC's serial packet:
-        * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>,
+       /*
+        * Construct and transmit target DAC's serial packet:
+        * (A10D DDDD), (DDDD DDDD), (0x0F), (0x00) where A is chan<0>,
         * and D<12:0> is the DAC setpoint.  Append a WORD value (that writes
         * to a  non-existent TrimDac channel) that serves to keep the clock
         * running after the packet has been sent to the target DAC.
         */
-       SendDAC(dev, 0x0F000000
-               /* Continue clock after target DAC data (write to non-existent trimdac). */
-               | 0x00004000
-               /* Address the two main dual-DAC devices (TSL's chip select enables
-                * target device). */
-               | ((uint32_t) (chan & 1) << 15)
-               /*  Address the DAC channel within the  device. */
-               | (uint32_t) dacdata);  /*  Include DAC setpoint data. */
-
+       val = 0x0F000000;       /* Continue clock after target DAC data
+                                * (write to non-existent trimdac). */
+       val |= 0x00004000;      /* Address the two main dual-DAC devices
+                                * (TSL's chip select enables target device). */
+       val |= ((uint32_t)(chan & 1) << 15);    /* Address the DAC channel
+                                                * within the device. */
+       val |= (uint32_t)dacdata;       /* Include DAC setpoint data. */
+       s626_send_dac(dev, val);
 }
 
-static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
-                        uint8_t DacData)
+static void s626_write_trim_dac(struct comedi_device *dev, uint8_t logical_chan,
+                               uint8_t dac_data)
 {
        struct s626_private *devpriv = dev->private;
        uint32_t chan;
 
-       /*  Save the new setpoint in case the application needs to read it back later. */
-       devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData;
+       /*
+        * Save the new setpoint in case the application needs to read it back
+        * later.
+        */
+       devpriv->trim_setpoint[logical_chan] = (uint8_t)dac_data;
 
-       /*  Map logical channel number to physical channel number. */
-       chan = (uint32_t) trimchan[LogicalChan];
+       /* Map logical channel number to physical channel number. */
+       chan = s626_trimchan[logical_chan];
 
-       /* Set up TSL2 records for TrimDac write operation.  All slots shift
+       /*
+        * Set up TSL2 records for TrimDac write operation.  All slots shift
         * 0xFF in from pulled-up SD3 so that the end of the slot sequence
         * can be detected.
         */
 
        /* Slot 2: Send high uint8_t to target TrimDac */
-       writel(XSD2 | XFIFO_1 | WS3, devpriv->mmio + VECTPORT(2));
+       writel(S626_XSD2 | S626_XFIFO_1 | S626_WS3,
+              devpriv->mmio + S626_VECTPORT(2));
        /* Slot 3: Send low uint8_t to target TrimDac */
-       writel(XSD2 | XFIFO_0 | WS3, devpriv->mmio + VECTPORT(3));
+       writel(S626_XSD2 | S626_XFIFO_0 | S626_WS3,
+              devpriv->mmio + S626_VECTPORT(3));
        /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running */
-       writel(XSD2 | XFIFO_3 | WS1, devpriv->mmio + VECTPORT(4));
+       writel(S626_XSD2 | S626_XFIFO_3 | S626_WS1,
+              devpriv->mmio + S626_VECTPORT(4));
        /* Slot 5: Send NOP low  uint8_t to DAC0 */
-       writel(XSD2 | XFIFO_2 | WS1 | EOS, devpriv->mmio + VECTPORT(5));
+       writel(S626_XSD2 | S626_XFIFO_2 | S626_WS1 | S626_EOS,
+              devpriv->mmio + S626_VECTPORT(5));
 
-       /* Construct and transmit target DAC's serial packet:
-        * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the
+       /*
+        * Construct and transmit target DAC's serial packet:
+        * (0000 AAAA), (DDDD DDDD), (0x00), (0x00) where A<3:0> is the
         * DAC channel's address, and D<7:0> is the DAC setpoint.  Append a
         * WORD value (that writes a channel 0 NOP command to a non-existent
         * main DAC channel) that serves to keep the clock running after the
         * packet has been sent to the target DAC.
         */
 
-       /*  Address the DAC channel within the trimdac device. */
-       SendDAC(dev, ((uint32_t) chan << 8)
-               | (uint32_t) DacData);  /*  Include DAC setpoint data. */
+       /*
+        * Address the DAC channel within the trimdac device.
+        * Include DAC setpoint data.
+        */
+       s626_send_dac(dev, (chan << 8) | dac_data);
 }
 
-static void LoadTrimDACs(struct comedi_device *dev)
+static void s626_load_trim_dacs(struct comedi_device *dev)
 {
-       register uint8_t i;
+       uint8_t i;
 
-       /*  Copy TrimDac setpoint values from EEPROM to TrimDacs. */
-       for (i = 0; i < ARRAY_SIZE(trimchan); i++)
-               WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i]));
+       /* Copy TrimDac setpoint values from EEPROM to TrimDacs. */
+       for (i = 0; i < ARRAY_SIZE(s626_trimchan); i++)
+               s626_write_trim_dac(dev, i,
+                                   s626_i2c_read(dev, s626_trimadrs[i]));
 }
 
 /* ******  COUNTER FUNCTIONS  ******* */
-/* All counter functions address a specific counter by means of the
+
+/*
+ * All counter functions address a specific counter by means of the
  * "Counter" argument, which is a logical counter number.  The Counter
  * argument may have any of the following legal values: 0=0A, 1=1A,
  * 2=2A, 3=0B, 4=1B, 5=2B.
  */
 
-/*  Read a counter's output latch. */
-static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k)
+/*
+ * Read a counter's output latch.
+ */
+static uint32_t s626_read_latch(struct comedi_device *dev,
+                               const struct s626_enc_info *k)
 {
-       register uint32_t value;
+       uint32_t value;
 
-       /*  Latch counts and fetch LSW of latched counts value. */
-       value = (uint32_t) DEBIread(dev, k->MyLatchLsw);
+       /* Latch counts and fetch LSW of latched counts value. */
+       value = s626_debi_read(dev, k->my_latch_lsw);
 
-       /*  Fetch MSW of latched counts and combine with LSW. */
-       value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16);
+       /* Fetch MSW of latched counts and combine with LSW. */
+       value |= ((uint32_t)s626_debi_read(dev, k->my_latch_lsw + 2) << 16);
 
-       /*  Return latched counts. */
+       /* Return latched counts. */
        return value;
 }
 
-/* Return/set a counter pair's latch trigger source.  0: On read
+/*
+ * Return/set a counter pair's latch trigger source.  0: On read
  * access, 1: A index latches A, 2: B index latches B, 3: A overflow
  * latches B.
  */
-static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
-                          uint16_t value)
+static void s626_set_latch_source(struct comedi_device *dev,
+                                 const struct s626_enc_info *k, uint16_t value)
 {
-       DEBIreplace(dev, k->MyCRB,
-                   ~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC),
-                   value << CRBBIT_LATCHSRC);
+       s626_debi_replace(dev, k->my_crb,
+                         ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_LATCHSRC),
+                         value << S626_CRBBIT_LATCHSRC);
 }
 
-/*  Write value into counter preload register. */
-static void Preload(struct comedi_device *dev, struct enc_private *k,
-                   uint32_t value)
+/*
+ * Write value into counter preload register.
+ */
+static void s626_preload(struct comedi_device *dev,
+                        const struct s626_enc_info *k, uint32_t value)
 {
-       DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value);
-       DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2),
-                 (uint16_t) (value >> 16));
+       s626_debi_write(dev, k->my_latch_lsw, value);
+       s626_debi_write(dev, k->my_latch_lsw + 2, value >> 16);
 }
 
-static unsigned int s626_ai_reg_to_uint(int data)
+/* ******  PRIVATE COUNTER FUNCTIONS ****** */
+
+/*
+ * Reset a counter's index and overflow event capture flags.
+ */
+static void s626_reset_cap_flags_a(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
 {
-       unsigned int tempdata;
+       s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
+                         S626_CRBMSK_INTRESETCMD | S626_CRBMSK_INTRESET_A);
+}
 
-       tempdata = (data >> 18);
-       if (tempdata & 0x2000)
-               tempdata &= 0x1fff;
-       else
-               tempdata += (1 << 13);
+static void s626_reset_cap_flags_b(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
+{
+       s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
+                         S626_CRBMSK_INTRESETCMD | S626_CRBMSK_INTRESET_B);
+}
+
+/*
+ * Return counter setup in a format (COUNTER_SETUP) that is consistent
+ * for both A and B counters.
+ */
+static uint16_t s626_get_mode_a(struct comedi_device *dev,
+                               const struct s626_enc_info *k)
+{
+       uint16_t cra;
+       uint16_t crb;
+       uint16_t setup;
+
+       /* Fetch CRA and CRB register images. */
+       cra = s626_debi_read(dev, k->my_cra);
+       crb = s626_debi_read(dev, k->my_crb);
+
+       /*
+        * Populate the standardized counter setup bit fields.
+        * Note: IndexSrc is restricted to ENC_X or IndxPol.
+        */
+       setup = (cra & S626_STDMSK_LOADSRC) |   /* LoadSrc  = LoadSrcA. */
+               ((crb << (S626_STDBIT_LATCHSRC - S626_CRBBIT_LATCHSRC)) &
+                S626_STDMSK_LATCHSRC) |        /* LatchSrc = LatchSrcA. */
+               ((cra << (S626_STDBIT_INTSRC - S626_CRABIT_INTSRC_A)) &
+                S626_STDMSK_INTSRC) |          /* IntSrc   = IntSrcA. */
+               ((cra << (S626_STDBIT_INDXSRC - (S626_CRABIT_INDXSRC_A + 1))) &
+                S626_STDMSK_INDXSRC) |         /* IndxSrc  = IndxSrcA<1>. */
+               ((cra >> (S626_CRABIT_INDXPOL_A - S626_STDBIT_INDXPOL)) &
+                S626_STDMSK_INDXPOL) |         /* IndxPol  = IndxPolA. */
+               ((crb >> (S626_CRBBIT_CLKENAB_A - S626_STDBIT_CLKENAB)) &
+                S626_STDMSK_CLKENAB);          /* ClkEnab  = ClkEnabA. */
+
+       /* Adjust mode-dependent parameters. */
+       if (cra & (S626_CNTSRC_SYSCLK << S626_CRABIT_CNTSRC_A)) {
+               /* Timer mode (CntSrcA<1> == 1): */
+               /* Indicate Timer mode. */
+               setup |= S626_ENCMODE_TIMER << S626_STDBIT_ENCMODE;
+               /* Set ClkPol to indicate count direction (CntSrcA<0>). */
+               setup |= (cra << (S626_STDBIT_CLKPOL - S626_CRABIT_CNTSRC_A)) &
+                        S626_STDMSK_CLKPOL;
+               /* ClkMult must be 1x in Timer mode. */
+               setup |= S626_MULT_X1 << S626_STDBIT_CLKMULT;
+       } else {
+               /* Counter mode (CntSrcA<1> == 0): */
+               /* Indicate Counter mode. */
+               setup |= S626_ENCMODE_COUNTER << S626_STDBIT_ENCMODE;
+               /* Pass through ClkPol. */
+               setup |= (cra >> (S626_CRABIT_CLKPOL_A - S626_STDBIT_CLKPOL)) &
+                        S626_STDMSK_CLKPOL;
+               /* Force ClkMult to 1x if not legal, else pass through. */
+               if ((cra & S626_CRAMSK_CLKMULT_A) ==
+                   (S626_MULT_X0 << S626_CRABIT_CLKMULT_A))
+                       setup |= S626_MULT_X1 << S626_STDBIT_CLKMULT;
+               else
+                       setup |= (cra >> (S626_CRABIT_CLKMULT_A -
+                                         S626_STDBIT_CLKMULT)) &
+                                S626_STDMSK_CLKMULT;
+       }
+
+       /* Return adjusted counter setup. */
+       return setup;
+}
+
+static uint16_t s626_get_mode_b(struct comedi_device *dev,
+                               const struct s626_enc_info *k)
+{
+       uint16_t cra;
+       uint16_t crb;
+       uint16_t setup;
+
+       /* Fetch CRA and CRB register images. */
+       cra = s626_debi_read(dev, k->my_cra);
+       crb = s626_debi_read(dev, k->my_crb);
+
+       /*
+        * Populate the standardized counter setup bit fields.
+        * Note: IndexSrc is restricted to ENC_X or IndxPol.
+        */
+       setup = ((crb << (S626_STDBIT_INTSRC - S626_CRBBIT_INTSRC_B)) &
+                S626_STDMSK_INTSRC) |          /* IntSrc   = IntSrcB. */
+               ((crb << (S626_STDBIT_LATCHSRC - S626_CRBBIT_LATCHSRC)) &
+                S626_STDMSK_LATCHSRC) |        /* LatchSrc = LatchSrcB. */
+               ((crb << (S626_STDBIT_LOADSRC - S626_CRBBIT_LOADSRC_B)) &
+                S626_STDMSK_LOADSRC) |         /* LoadSrc  = LoadSrcB. */
+               ((crb << (S626_STDBIT_INDXPOL - S626_CRBBIT_INDXPOL_B)) &
+                S626_STDMSK_INDXPOL) |         /* IndxPol  = IndxPolB. */
+               ((crb >> (S626_CRBBIT_CLKENAB_B - S626_STDBIT_CLKENAB)) &
+                S626_STDMSK_CLKENAB) |         /* ClkEnab  = ClkEnabB. */
+               ((cra >> ((S626_CRABIT_INDXSRC_B + 1) - S626_STDBIT_INDXSRC)) &
+                S626_STDMSK_INDXSRC);          /* IndxSrc  = IndxSrcB<1>. */
+
+       /* Adjust mode-dependent parameters. */
+       if ((crb & S626_CRBMSK_CLKMULT_B) ==
+           (S626_MULT_X0 << S626_CRBBIT_CLKMULT_B)) {
+               /* Extender mode (ClkMultB == S626_MULT_X0): */
+               /* Indicate Extender mode. */
+               setup |= S626_ENCMODE_EXTENDER << S626_STDBIT_ENCMODE;
+               /* Indicate multiplier is 1x. */
+               setup |= S626_MULT_X1 << S626_STDBIT_CLKMULT;
+               /* Set ClkPol equal to Timer count direction (CntSrcB<0>). */
+               setup |= (cra >> (S626_CRABIT_CNTSRC_B - S626_STDBIT_CLKPOL)) &
+                        S626_STDMSK_CLKPOL;
+       } else if (cra & (S626_CNTSRC_SYSCLK << S626_CRABIT_CNTSRC_B)) {
+               /* Timer mode (CntSrcB<1> == 1): */
+               /* Indicate Timer mode. */
+               setup |= S626_ENCMODE_TIMER << S626_STDBIT_ENCMODE;
+               /* Indicate multiplier is 1x. */
+               setup |= S626_MULT_X1 << S626_STDBIT_CLKMULT;
+               /* Set ClkPol equal to Timer count direction (CntSrcB<0>). */
+               setup |= (cra >> (S626_CRABIT_CNTSRC_B - S626_STDBIT_CLKPOL)) &
+                        S626_STDMSK_CLKPOL;
+       } else {
+               /* If Counter mode (CntSrcB<1> == 0): */
+               /* Indicate Counter mode. */
+               setup |= S626_ENCMODE_COUNTER << S626_STDBIT_ENCMODE;
+               /* Clock multiplier is passed through. */
+               setup |= (crb >> (S626_CRBBIT_CLKMULT_B -
+                                 S626_STDBIT_CLKMULT)) & S626_STDMSK_CLKMULT;
+               /* Clock polarity is passed through. */
+               setup |= (crb << (S626_STDBIT_CLKPOL - S626_CRBBIT_CLKPOL_B)) &
+                        S626_STDMSK_CLKPOL;
+       }
+
+       /* Return adjusted counter setup. */
+       return setup;
+}
+
+/*
+ * Set the operating mode for the specified counter.  The setup
+ * parameter is treated as a COUNTER_SETUP data type.  The following
+ * parameters are programmable (all other parms are ignored): ClkMult,
+ * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
+ */
+static void s626_set_mode_a(struct comedi_device *dev,
+                           const struct s626_enc_info *k, uint16_t setup,
+                           uint16_t disable_int_src)
+{
+       struct s626_private *devpriv = dev->private;
+       uint16_t cra;
+       uint16_t crb;
+
+       /* Initialize CRA and CRB images. */
+       /* Preload trigger is passed through. */
+       cra = setup & S626_CRAMSK_LOADSRC_A;
+       /* IndexSrc is restricted to ENC_X or IndxPol. */
+       cra |= (setup & S626_STDMSK_INDXSRC) >>
+              (S626_STDBIT_INDXSRC - (S626_CRABIT_INDXSRC_A + 1));
+
+       /* Reset any pending CounterA event captures. */
+       crb = S626_CRBMSK_INTRESETCMD | S626_CRBMSK_INTRESET_A;
+       /* Clock enable is passed through. */
+       crb |= (setup & S626_STDMSK_CLKENAB) <<
+              (S626_CRBBIT_CLKENAB_A - S626_STDBIT_CLKENAB);
+
+       /* Force IntSrc to Disabled if disable_int_src is asserted. */
+       if (!disable_int_src)
+               cra |= (setup & S626_STDMSK_INTSRC) >>
+                      (S626_STDBIT_INTSRC - S626_CRABIT_INTSRC_A);
+
+       /* Populate all mode-dependent attributes of CRA & CRB images. */
+       switch ((setup & S626_STDMSK_ENCMODE) >> S626_STDBIT_ENCMODE) {
+       case S626_ENCMODE_EXTENDER: /* Extender Mode: */
+               /* Force to Timer mode (Extender valid only for B counters). */
+               /* Fall through to case S626_ENCMODE_TIMER: */
+       case S626_ENCMODE_TIMER:        /* Timer Mode: */
+               /* CntSrcA<1> selects system clock */
+               cra |= S626_CNTSRC_SYSCLK << S626_CRABIT_CNTSRC_A;
+               /* Count direction (CntSrcA<0>) obtained from ClkPol. */
+               cra |= (setup & S626_STDMSK_CLKPOL) >>
+                      (S626_STDBIT_CLKPOL - S626_CRABIT_CNTSRC_A);
+               /* ClkPolA behaves as always-on clock enable. */
+               cra |= 1 << S626_CRABIT_CLKPOL_A;
+               /* ClkMult must be 1x. */
+               cra |= S626_MULT_X1 << S626_CRABIT_CLKMULT_A;
+               break;
+       default:                /* Counter Mode: */
+               /* Select ENC_C and ENC_D as clock/direction inputs. */
+               cra |= S626_CNTSRC_ENCODER << S626_CRABIT_CNTSRC_A;
+               /* Clock polarity is passed through. */
+               cra |= (setup & S626_STDMSK_CLKPOL) <<
+                      (S626_CRABIT_CLKPOL_A - S626_STDBIT_CLKPOL);
+               /* Force multiplier to x1 if not legal, else pass through. */
+               if ((setup & S626_STDMSK_CLKMULT) ==
+                   (S626_MULT_X0 << S626_STDBIT_CLKMULT))
+                       cra |= S626_MULT_X1 << S626_CRABIT_CLKMULT_A;
+               else
+                       cra |= (setup & S626_STDMSK_CLKMULT) <<
+                              (S626_CRABIT_CLKMULT_A - S626_STDBIT_CLKMULT);
+               break;
+       }
+
+       /*
+        * Force positive index polarity if IndxSrc is software-driven only,
+        * otherwise pass it through.
+        */
+       if (~setup & S626_STDMSK_INDXSRC)
+               cra |= (setup & S626_STDMSK_INDXPOL) <<
+                      (S626_CRABIT_INDXPOL_A - S626_STDBIT_INDXPOL);
+
+       /*
+        * If IntSrc has been forced to Disabled, update the MISC2 interrupt
+        * enable mask to indicate the counter interrupt is disabled.
+        */
+       if (disable_int_src)
+               devpriv->counter_int_enabs &= ~k->my_event_bits[3];
+
+       /*
+        * While retaining CounterB and LatchSrc configurations, program the
+        * new counter operating mode.
+        */
+       s626_debi_replace(dev, k->my_cra,
+                         S626_CRAMSK_INDXSRC_B | S626_CRAMSK_CNTSRC_B, cra);
+       s626_debi_replace(dev, k->my_crb,
+                         ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_A), crb);
+}
+
+static void s626_set_mode_b(struct comedi_device *dev,
+                           const struct s626_enc_info *k, uint16_t setup,
+                           uint16_t disable_int_src)
+{
+       struct s626_private *devpriv = dev->private;
+       uint16_t cra;
+       uint16_t crb;
+
+       /* Initialize CRA and CRB images. */
+       /* IndexSrc field is restricted to ENC_X or IndxPol. */
+       cra = (setup & S626_STDMSK_INDXSRC) <<
+             (S626_CRABIT_INDXSRC_B + 1 - S626_STDBIT_INDXSRC);
+
+       /* Reset event captures and disable interrupts. */
+       crb = S626_CRBMSK_INTRESETCMD | S626_CRBMSK_INTRESET_B;
+       /* Clock enable is passed through. */
+       crb |= (setup & S626_STDMSK_CLKENAB) <<
+              (S626_CRBBIT_CLKENAB_B - S626_STDBIT_CLKENAB);
+       /* Preload trigger source is passed through. */
+       crb |= (setup & S626_STDMSK_LOADSRC) >>
+              (S626_STDBIT_LOADSRC - S626_CRBBIT_LOADSRC_B);
+
+       /* Force IntSrc to Disabled if disable_int_src is asserted. */
+       if (!disable_int_src)
+               crb |= (setup & S626_STDMSK_INTSRC) >>
+                      (S626_STDBIT_INTSRC - S626_CRBBIT_INTSRC_B);
+
+       /* Populate all mode-dependent attributes of CRA & CRB images. */
+       switch ((setup & S626_STDMSK_ENCMODE) >> S626_STDBIT_ENCMODE) {
+       case S626_ENCMODE_TIMER:        /* Timer Mode: */
+               /* CntSrcB<1> selects system clock */
+               cra |= S626_CNTSRC_SYSCLK << S626_CRABIT_CNTSRC_B;
+               /* with direction (CntSrcB<0>) obtained from ClkPol. */
+               cra |= (setup & S626_STDMSK_CLKPOL) <<
+                      (S626_CRABIT_CNTSRC_B - S626_STDBIT_CLKPOL);
+               /* ClkPolB behaves as always-on clock enable. */
+               crb |= 1 << S626_CRBBIT_CLKPOL_B;
+               /* ClkMultB must be 1x. */
+               crb |= S626_MULT_X1 << S626_CRBBIT_CLKMULT_B;
+               break;
+       case S626_ENCMODE_EXTENDER:     /* Extender Mode: */
+               /* CntSrcB source is OverflowA (same as "timer") */
+               cra |= S626_CNTSRC_SYSCLK << S626_CRABIT_CNTSRC_B;
+               /* with direction obtained from ClkPol. */
+               cra |= (setup & S626_STDMSK_CLKPOL) <<
+                      (S626_CRABIT_CNTSRC_B - S626_STDBIT_CLKPOL);
+               /* ClkPolB controls IndexB -- always set to active. */
+               crb |= 1 << S626_CRBBIT_CLKPOL_B;
+               /* ClkMultB selects OverflowA as the clock source. */
+               crb |= S626_MULT_X0 << S626_CRBBIT_CLKMULT_B;
+               break;
+       default:                /* Counter Mode: */
+               /* Select ENC_C and ENC_D as clock/direction inputs. */
+               cra |= S626_CNTSRC_ENCODER << S626_CRABIT_CNTSRC_B;
+               /* ClkPol is passed through. */
+               crb |= (setup & S626_STDMSK_CLKPOL) >>
+                      (S626_STDBIT_CLKPOL - S626_CRBBIT_CLKPOL_B);
+               /* Force ClkMult to x1 if not legal, otherwise pass through. */
+               if ((setup & S626_STDMSK_CLKMULT) ==
+                   (S626_MULT_X0 << S626_STDBIT_CLKMULT))
+                       crb |= S626_MULT_X1 << S626_CRBBIT_CLKMULT_B;
+               else
+                       crb |= (setup & S626_STDMSK_CLKMULT) <<
+                              (S626_CRBBIT_CLKMULT_B - S626_STDBIT_CLKMULT);
+               break;
+       }
+
+       /*
+        * Force positive index polarity if IndxSrc is software-driven only,
+        * otherwise pass it through.
+        */
+       if (~setup & S626_STDMSK_INDXSRC)
+               crb |= (setup & S626_STDMSK_INDXPOL) >>
+                      (S626_STDBIT_INDXPOL - S626_CRBBIT_INDXPOL_B);
+
+       /*
+        * If IntSrc has been forced to Disabled, update the MISC2 interrupt
+        * enable mask to indicate the counter interrupt is disabled.
+        */
+       if (disable_int_src)
+               devpriv->counter_int_enabs &= ~k->my_event_bits[3];
+
+       /*
+        * While retaining CounterA and LatchSrc configurations, program the
+        * new counter operating mode.
+        */
+       s626_debi_replace(dev, k->my_cra,
+                         ~(S626_CRAMSK_INDXSRC_B | S626_CRAMSK_CNTSRC_B), cra);
+       s626_debi_replace(dev, k->my_crb,
+                         S626_CRBMSK_CLKENAB_A | S626_CRBMSK_LATCHSRC, crb);
+}
+
+/*
+ * Return/set a counter's enable.  enab: 0=always enabled, 1=enabled by index.
+ */
+static void s626_set_enable_a(struct comedi_device *dev,
+                             const struct s626_enc_info *k, uint16_t enab)
+{
+       s626_debi_replace(dev, k->my_crb,
+                         ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_A),
+                         enab << S626_CRBBIT_CLKENAB_A);
+}
+
+static void s626_set_enable_b(struct comedi_device *dev,
+                             const struct s626_enc_info *k, uint16_t enab)
+{
+       s626_debi_replace(dev, k->my_crb,
+                         ~(S626_CRBMSK_INTCTRL | S626_CRBMSK_CLKENAB_B),
+                         enab << S626_CRBBIT_CLKENAB_B);
+}
+
+static uint16_t s626_get_enable_a(struct comedi_device *dev,
+                                 const struct s626_enc_info *k)
+{
+       return (s626_debi_read(dev, k->my_crb) >> S626_CRBBIT_CLKENAB_A) & 1;
+}
+
+static uint16_t s626_get_enable_b(struct comedi_device *dev,
+                                 const struct s626_enc_info *k)
+{
+       return (s626_debi_read(dev, k->my_crb) >> S626_CRBBIT_CLKENAB_B) & 1;
+}
+
+#ifdef unused
+static uint16_t s626_get_latch_source(struct comedi_device *dev,
+                                     const struct s626_enc_info *k)
+{
+       return (s626_debi_read(dev, k->my_crb) >> S626_CRBBIT_LATCHSRC) & 3;
+}
+#endif
+
+/*
+ * Return/set the event that will trigger transfer of the preload
+ * register into the counter.  0=ThisCntr_Index, 1=ThisCntr_Overflow,
+ * 2=OverflowA (B counters only), 3=disabled.
+ */
+static void s626_set_load_trig_a(struct comedi_device *dev,
+                                const struct s626_enc_info *k, uint16_t trig)
+{
+       s626_debi_replace(dev, k->my_cra, ~S626_CRAMSK_LOADSRC_A,
+                         trig << S626_CRABIT_LOADSRC_A);
+}
+
+static void s626_set_load_trig_b(struct comedi_device *dev,
+                                const struct s626_enc_info *k, uint16_t trig)
+{
+       s626_debi_replace(dev, k->my_crb,
+                         ~(S626_CRBMSK_LOADSRC_B | S626_CRBMSK_INTCTRL),
+                         trig << S626_CRBBIT_LOADSRC_B);
+}
+
+static uint16_t s626_get_load_trig_a(struct comedi_device *dev,
+                                    const struct s626_enc_info *k)
+{
+       return (s626_debi_read(dev, k->my_cra) >> S626_CRABIT_LOADSRC_A) & 3;
+}
+
+static uint16_t s626_get_load_trig_b(struct comedi_device *dev,
+                                    const struct s626_enc_info *k)
+{
+       return (s626_debi_read(dev, k->my_crb) >> S626_CRBBIT_LOADSRC_B) & 3;
+}
+
+/*
+ * Return/set counter interrupt source and clear any captured
+ * index/overflow events.  int_source: 0=Disabled, 1=OverflowOnly,
+ * 2=IndexOnly, 3=IndexAndOverflow.
+ */
+static void s626_set_int_src_a(struct comedi_device *dev,
+                              const struct s626_enc_info *k,
+                              uint16_t int_source)
+{
+       struct s626_private *devpriv = dev->private;
+
+       /* Reset any pending counter overflow or index captures. */
+       s626_debi_replace(dev, k->my_crb, ~S626_CRBMSK_INTCTRL,
+                         S626_CRBMSK_INTRESETCMD | S626_CRBMSK_INTRESET_A);
+
+       /* Program counter interrupt source. */
+       s626_debi_replace(dev, k->my_cra, ~S626_CRAMSK_INTSRC_A,
+                         int_source << S626_CRABIT_INTSRC_A);
+
+       /* Update MISC2 interrupt enable mask. */
+       devpriv->counter_int_enabs =
+           (devpriv->counter_int_enabs & ~k->my_event_bits[3]) |
+           k->my_event_bits[int_source];
+}
+
+static void s626_set_int_src_b(struct comedi_device *dev,
+                              const struct s626_enc_info *k,
+                              uint16_t int_source)
+{
+       struct s626_private *devpriv = dev->private;
+       uint16_t crb;
+
+       /* Cache writeable CRB register image. */
+       crb = s626_debi_read(dev, k->my_crb) & ~S626_CRBMSK_INTCTRL;
+
+       /* Reset any pending counter overflow or index captures. */
+       s626_debi_write(dev, k->my_crb, (crb | S626_CRBMSK_INTRESETCMD |
+                                        S626_CRBMSK_INTRESET_B));
+
+       /* Program counter interrupt source. */
+       s626_debi_write(dev, k->my_crb,
+                       ((crb & ~S626_CRBMSK_INTSRC_B) |
+                        (int_source << S626_CRBBIT_INTSRC_B)));
+
+       /* Update MISC2 interrupt enable mask. */
+       devpriv->counter_int_enabs =
+               (devpriv->counter_int_enabs & ~k->my_event_bits[3]) |
+               k->my_event_bits[int_source];
+}
+
+static uint16_t s626_get_int_src_a(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
+{
+       return (s626_debi_read(dev, k->my_cra) >> S626_CRABIT_INTSRC_A) & 3;
+}
+
+static uint16_t s626_get_int_src_b(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
+{
+       return (s626_debi_read(dev, k->my_crb) >> S626_CRBBIT_INTSRC_B) & 3;
+}
+
+#ifdef unused
+/*
+ * Return/set the clock multiplier.
+ */
+static void s626_set_clk_mult(struct comedi_device *dev,
+                             const struct s626_enc_info *k, uint16_t value)
+{
+       k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_CLKMULT) |
+                           (value << S626_STDBIT_CLKMULT)), false);
+}
+
+static uint16_t s626_get_clk_mult(struct comedi_device *dev,
+                                 const struct s626_enc_info *k)
+{
+       return (k->get_mode(dev, k) >> S626_STDBIT_CLKMULT) & 3;
+}
+
+/*
+ * Return/set the clock polarity.
+ */
+static void s626_set_clk_pol(struct comedi_device *dev,
+                            const struct s626_enc_info *k, uint16_t value)
+{
+       k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_CLKPOL) |
+                           (value << S626_STDBIT_CLKPOL)), false);
+}
+
+static uint16_t s626_get_clk_pol(struct comedi_device *dev,
+                                const struct s626_enc_info *k)
+{
+       return (k->get_mode(dev, k) >> S626_STDBIT_CLKPOL) & 1;
+}
+
+/*
+ * Return/set the encoder mode.
+ */
+static void s626_set_enc_mode(struct comedi_device *dev,
+                             const struct s626_enc_info *k, uint16_t value)
+{
+       k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_ENCMODE) |
+                           (value << S626_STDBIT_ENCMODE)), false);
+}
+
+static uint16_t s626_get_enc_mode(struct comedi_device *dev,
+                                 const struct s626_enc_info *k)
+{
+       return (k->get_mode(dev, k) >> S626_STDBIT_ENCMODE) & 3;
+}
+
+/*
+ * Return/set the index polarity.
+ */
+static void s626_set_index_pol(struct comedi_device *dev,
+                              const struct s626_enc_info *k, uint16_t value)
+{
+       k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_INDXPOL) |
+                           ((value != 0) << S626_STDBIT_INDXPOL)), false);
+}
+
+static uint16_t s626_get_index_pol(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
+{
+       return (k->get_mode(dev, k) >> S626_STDBIT_INDXPOL) & 1;
+}
+
+/*
+ * Return/set the index source.
+ */
+static void s626_set_index_src(struct comedi_device *dev,
+                              const struct s626_enc_info *k, uint16_t value)
+{
+       k->set_mode(dev, k, ((k->get_mode(dev, k) & ~S626_STDMSK_INDXSRC) |
+                           ((value != 0) << S626_STDBIT_INDXSRC)), false);
+}
+
+static uint16_t s626_get_index_src(struct comedi_device *dev,
+                                  const struct s626_enc_info *k)
+{
+       return (k->get_mode(dev, k) >> S626_STDBIT_INDXSRC) & 1;
+}
+#endif
 
-       return tempdata;
+/*
+ * Generate an index pulse.
+ */
+static void s626_pulse_index_a(struct comedi_device *dev,
+                              const struct s626_enc_info *k)
+{
+       uint16_t cra;
+
+       cra = s626_debi_read(dev, k->my_cra);
+       /* Pulse index. */
+       s626_debi_write(dev, k->my_cra, (cra ^ S626_CRAMSK_INDXPOL_A));
+       s626_debi_write(dev, k->my_cra, cra);
 }
 
-/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data){ */
-/*   return 0; */
-/* } */
+static void s626_pulse_index_b(struct comedi_device *dev,
+                              const struct s626_enc_info *k)
+{
+       uint16_t crb;
+
+       crb = s626_debi_read(dev, k->my_crb) & ~S626_CRBMSK_INTCTRL;
+       /* Pulse index. */
+       s626_debi_write(dev, k->my_crb, (crb ^ S626_CRBMSK_INDXPOL_B));
+       s626_debi_write(dev, k->my_crb, crb);
+}
+
+static const struct s626_enc_info s626_enc_chan_info[] = {
+       {
+               .get_enable             = s626_get_enable_a,
+               .get_int_src            = s626_get_int_src_a,
+               .get_load_trig          = s626_get_load_trig_a,
+               .get_mode               = s626_get_mode_a,
+               .pulse_index            = s626_pulse_index_a,
+               .set_enable             = s626_set_enable_a,
+               .set_int_src            = s626_set_int_src_a,
+               .set_load_trig          = s626_set_load_trig_a,
+               .set_mode               = s626_set_mode_a,
+               .reset_cap_flags        = s626_reset_cap_flags_a,
+               .my_cra                 = S626_LP_CR0A,
+               .my_crb                 = S626_LP_CR0B,
+               .my_latch_lsw           = S626_LP_CNTR0ALSW,
+               .my_event_bits          = S626_EVBITS(0),
+       }, {
+               .get_enable             = s626_get_enable_a,
+               .get_int_src            = s626_get_int_src_a,
+               .get_load_trig          = s626_get_load_trig_a,
+               .get_mode               = s626_get_mode_a,
+               .pulse_index            = s626_pulse_index_a,
+               .set_enable             = s626_set_enable_a,
+               .set_int_src            = s626_set_int_src_a,
+               .set_load_trig          = s626_set_load_trig_a,
+               .set_mode               = s626_set_mode_a,
+               .reset_cap_flags        = s626_reset_cap_flags_a,
+               .my_cra                 = S626_LP_CR1A,
+               .my_crb                 = S626_LP_CR1B,
+               .my_latch_lsw           = S626_LP_CNTR1ALSW,
+               .my_event_bits          = S626_EVBITS(1),
+       }, {
+               .get_enable             = s626_get_enable_a,
+               .get_int_src            = s626_get_int_src_a,
+               .get_load_trig          = s626_get_load_trig_a,
+               .get_mode               = s626_get_mode_a,
+               .pulse_index            = s626_pulse_index_a,
+               .set_enable             = s626_set_enable_a,
+               .set_int_src            = s626_set_int_src_a,
+               .set_load_trig          = s626_set_load_trig_a,
+               .set_mode               = s626_set_mode_a,
+               .reset_cap_flags        = s626_reset_cap_flags_a,
+               .my_cra                 = S626_LP_CR2A,
+               .my_crb                 = S626_LP_CR2B,
+               .my_latch_lsw           = S626_LP_CNTR2ALSW,
+               .my_event_bits          = S626_EVBITS(2),
+       }, {
+               .get_enable             = s626_get_enable_b,
+               .get_int_src            = s626_get_int_src_b,
+               .get_load_trig          = s626_get_load_trig_b,
+               .get_mode               = s626_get_mode_b,
+               .pulse_index            = s626_pulse_index_b,
+               .set_enable             = s626_set_enable_b,
+               .set_int_src            = s626_set_int_src_b,
+               .set_load_trig          = s626_set_load_trig_b,
+               .set_mode               = s626_set_mode_b,
+               .reset_cap_flags        = s626_reset_cap_flags_b,
+               .my_cra                 = S626_LP_CR0A,
+               .my_crb                 = S626_LP_CR0B,
+               .my_latch_lsw           = S626_LP_CNTR0BLSW,
+               .my_event_bits          = S626_EVBITS(3),
+       }, {
+               .get_enable             = s626_get_enable_b,
+               .get_int_src            = s626_get_int_src_b,
+               .get_load_trig          = s626_get_load_trig_b,
+               .get_mode               = s626_get_mode_b,
+               .pulse_index            = s626_pulse_index_b,
+               .set_enable             = s626_set_enable_b,
+               .set_int_src            = s626_set_int_src_b,
+               .set_load_trig          = s626_set_load_trig_b,
+               .set_mode               = s626_set_mode_b,
+               .reset_cap_flags        = s626_reset_cap_flags_b,
+               .my_cra                 = S626_LP_CR1A,
+               .my_crb                 = S626_LP_CR1B,
+               .my_latch_lsw           = S626_LP_CNTR1BLSW,
+               .my_event_bits          = S626_EVBITS(4),
+       }, {
+               .get_enable             = s626_get_enable_b,
+               .get_int_src            = s626_get_int_src_b,
+               .get_load_trig          = s626_get_load_trig_b,
+               .get_mode               = s626_get_mode_b,
+               .pulse_index            = s626_pulse_index_b,
+               .set_enable             = s626_set_enable_b,
+               .set_int_src            = s626_set_int_src_b,
+               .set_load_trig          = s626_set_load_trig_b,
+               .set_mode               = s626_set_mode_b,
+               .reset_cap_flags        = s626_reset_cap_flags_b,
+               .my_cra                 = S626_LP_CR2A,
+               .my_crb                 = S626_LP_CR2B,
+               .my_latch_lsw           = S626_LP_CNTR2BLSW,
+               .my_event_bits          = S626_EVBITS(5),
+       },
+};
+
+static unsigned int s626_ai_reg_to_uint(unsigned int data)
+{
+       return ((data >> 18) & 0x3fff) ^ 0x2000;
+}
 
 static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
 {
@@ -629,19 +1341,19 @@ static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
        unsigned int status;
 
        /* set channel to capture positive edge */
-       status = DEBIread(dev, LP_RDEDGSEL(group));
-       DEBIwrite(dev, LP_WREDGSEL(group), mask | status);
+       status = s626_debi_read(dev, S626_LP_RDEDGSEL(group));
+       s626_debi_write(dev, S626_LP_WREDGSEL(group), mask | status);
 
        /* enable interrupt on selected channel */
-       status = DEBIread(dev, LP_RDINTSEL(group));
-       DEBIwrite(dev, LP_WRINTSEL(group), mask | status);
+       status = s626_debi_read(dev, S626_LP_RDINTSEL(group));
+       s626_debi_write(dev, S626_LP_WRINTSEL(group), mask | status);
 
        /* enable edge capture write command */
-       DEBIwrite(dev, LP_MISC1, MISC1_EDCAP);
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_EDCAP);
 
        /* enable edge capture on selected channel */
-       status = DEBIread(dev, LP_RDCAPSEL(group));
-       DEBIwrite(dev, LP_WRCAPSEL(group), mask | status);
+       status = s626_debi_read(dev, S626_LP_RDCAPSEL(group));
+       s626_debi_write(dev, S626_LP_WRCAPSEL(group), mask | status);
 
        return 0;
 }
@@ -650,10 +1362,10 @@ static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
                              unsigned int mask)
 {
        /* disable edge capture write command */
-       DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_NOEDCAP);
 
        /* enable edge capture on selected channel */
-       DEBIwrite(dev, LP_WRCAPSEL(group), mask);
+       s626_debi_write(dev, S626_LP_WRCAPSEL(group), mask);
 
        return 0;
 }
@@ -663,17 +1375,17 @@ static int s626_dio_clear_irq(struct comedi_device *dev)
        unsigned int group;
 
        /* disable edge capture write command */
-       DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_NOEDCAP);
 
        /* clear all dio pending events and interrupt */
        for (group = 0; group < S626_DIO_BANKS; group++)
-               DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff);
+               s626_debi_write(dev, S626_LP_WRCAPSEL(group), 0xffff);
 
        return 0;
 }
 
-static void handle_dio_interrupt(struct comedi_device *dev,
-                                uint16_t irqbit, uint8_t group)
+static void s626_handle_dio_interrupt(struct comedi_device *dev,
+                                     uint16_t irqbit, uint8_t group)
 {
        struct s626_private *devpriv = dev->private;
        struct comedi_subdevice *s = dev->read_subdev;
@@ -686,7 +1398,7 @@ static void handle_dio_interrupt(struct comedi_device *dev,
                if ((irqbit >> (cmd->start_arg - (16 * group))) == 1 &&
                    cmd->start_src == TRIG_EXT) {
                        /* Start executing the RPS program */
-                       s626_mc_enable(dev, MC1_ERPS1, P_MC1);
+                       s626_mc_enable(dev, S626_MC1_ERPS1, S626_P_MC1);
 
                        if (cmd->scan_begin_src == TRIG_EXT)
                                s626_dio_set_irq(dev, cmd->scan_begin_arg);
@@ -694,7 +1406,7 @@ static void handle_dio_interrupt(struct comedi_device *dev,
                if ((irqbit >> (cmd->scan_begin_arg - (16 * group))) == 1 &&
                    cmd->scan_begin_src == TRIG_EXT) {
                        /* Trigger ADC scan loop start */
-                       s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+                       s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
 
                        if (cmd->convert_src == TRIG_EXT) {
                                devpriv->ai_convert_count = cmd->chanlist_len;
@@ -703,16 +1415,17 @@ static void handle_dio_interrupt(struct comedi_device *dev,
                        }
 
                        if (cmd->convert_src == TRIG_TIMER) {
-                               struct enc_private *k = &encpriv[5];
+                               const struct s626_enc_info *k =
+                                       &s626_enc_chan_info[5];
 
                                devpriv->ai_convert_count = cmd->chanlist_len;
-                               k->SetEnable(dev, k, CLKENAB_ALWAYS);
+                               k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
                        }
                }
                if ((irqbit >> (cmd->convert_arg - (16 * group))) == 1 &&
                    cmd->convert_src == TRIG_EXT) {
                        /* Trigger ADC scan loop start */
-                       s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+                       s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
 
                        devpriv->ai_convert_count--;
                        if (devpriv->ai_convert_count > 0)
@@ -721,7 +1434,7 @@ static void handle_dio_interrupt(struct comedi_device *dev,
        }
 }
 
-static void check_dio_interrupts(struct comedi_device *dev)
+static void s626_check_dio_interrupts(struct comedi_device *dev)
 {
        uint16_t irqbit;
        uint8_t group;
@@ -729,90 +1442,91 @@ static void check_dio_interrupts(struct comedi_device *dev)
        for (group = 0; group < S626_DIO_BANKS; group++) {
                irqbit = 0;
                /* read interrupt type */
-               irqbit = DEBIread(dev, LP_RDCAPFLG(group));
+               irqbit = s626_debi_read(dev, S626_LP_RDCAPFLG(group));
 
                /* check if interrupt is generated from dio channels */
                if (irqbit) {
-                       handle_dio_interrupt(dev, irqbit, group);
+                       s626_handle_dio_interrupt(dev, irqbit, group);
                        return;
                }
        }
 }
 
-static void check_counter_interrupts(struct comedi_device *dev)
+static void s626_check_counter_interrupts(struct comedi_device *dev)
 {
        struct s626_private *devpriv = dev->private;
        struct comedi_subdevice *s = dev->read_subdev;
        struct comedi_async *async = s->async;
        struct comedi_cmd *cmd = &async->cmd;
-       struct enc_private *k;
+       const struct s626_enc_info *k;
        uint16_t irqbit;
 
        /* read interrupt type */
-       irqbit = DEBIread(dev, LP_RDMISC2);
+       irqbit = s626_debi_read(dev, S626_LP_RDMISC2);
 
        /* check interrupt on counters */
-       if (irqbit & IRQ_COINT1A) {
-               k = &encpriv[0];
+       if (irqbit & S626_IRQ_COINT1A) {
+               k = &s626_enc_chan_info[0];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
        }
-       if (irqbit & IRQ_COINT2A) {
-               k = &encpriv[1];
+       if (irqbit & S626_IRQ_COINT2A) {
+               k = &s626_enc_chan_info[1];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
        }
-       if (irqbit & IRQ_COINT3A) {
-               k = &encpriv[2];
+       if (irqbit & S626_IRQ_COINT3A) {
+               k = &s626_enc_chan_info[2];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
        }
-       if (irqbit & IRQ_COINT1B) {
-               k = &encpriv[3];
+       if (irqbit & S626_IRQ_COINT1B) {
+               k = &s626_enc_chan_info[3];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
        }
-       if (irqbit & IRQ_COINT2B) {
-               k = &encpriv[4];
+       if (irqbit & S626_IRQ_COINT2B) {
+               k = &s626_enc_chan_info[4];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
 
                if (devpriv->ai_convert_count > 0) {
                        devpriv->ai_convert_count--;
                        if (devpriv->ai_convert_count == 0)
-                               k->SetEnable(dev, k, CLKENAB_INDEX);
+                               k->set_enable(dev, k, S626_CLKENAB_INDEX);
 
                        if (cmd->convert_src == TRIG_TIMER) {
                                /* Trigger ADC scan loop start */
-                               s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+                               s626_mc_enable(dev, S626_MC2_ADC_RPS,
+                                              S626_P_MC2);
                        }
                }
        }
-       if (irqbit & IRQ_COINT3B) {
-               k = &encpriv[5];
+       if (irqbit & S626_IRQ_COINT3B) {
+               k = &s626_enc_chan_info[5];
 
                /* clear interrupt capture flag */
-               k->ResetCapFlags(dev, k);
+               k->reset_cap_flags(dev, k);
 
                if (cmd->scan_begin_src == TRIG_TIMER) {
                        /* Trigger ADC scan loop start */
-                       s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+                       s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
                }
 
                if (cmd->convert_src == TRIG_TIMER) {
-                       k = &encpriv[4];
+                       k = &s626_enc_chan_info[4];
                        devpriv->ai_convert_count = cmd->chanlist_len;
-                       k->SetEnable(dev, k, CLKENAB_ALWAYS);
+                       k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
                }
        }
 }
 
-static bool handle_eos_interrupt(struct comedi_device *dev)
+static bool s626_handle_eos_interrupt(struct comedi_device *dev)
 {
        struct s626_private *devpriv = dev->private;
        struct comedi_subdevice *s = dev->read_subdev;
@@ -823,19 +1537,19 @@ static bool handle_eos_interrupt(struct comedi_device *dev)
         * first uint16_t in the buffer because it contains junk data
         * from the final ADC of the previous poll list scan.
         */
-       int32_t *readaddr = (int32_t *)devpriv->ANABuf.LogicalBase + 1;
+       uint32_t *readaddr = (uint32_t *)devpriv->ana_buf.logical_base + 1;
        bool finished = false;
        int i;
 
        /* get the data and hand it over to comedi */
        for (i = 0; i < cmd->chanlist_len; i++) {
-               short tempdata;
+               unsigned short tempdata;
 
                /*
                 * Convert ADC data to 16-bit integer values and copy
                 * to application buffer.
                 */
-               tempdata = s626_ai_reg_to_uint((int)*readaddr);
+               tempdata = s626_ai_reg_to_uint(*readaddr);
                readaddr++;
 
                /* put data into read buffer */
@@ -846,13 +1560,13 @@ static bool handle_eos_interrupt(struct comedi_device *dev)
        /* end of scan occurs */
        async->events |= COMEDI_CB_EOS;
 
-       if (!devpriv->ai_continous)
+       if (!devpriv->ai_continuous)
                devpriv->ai_sample_count--;
        if (devpriv->ai_sample_count <= 0) {
                devpriv->ai_cmd_running = 0;
 
                /* Stop RPS program */
-               s626_mc_disable(dev, MC1_ERPS1, P_MC1);
+               s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1);
 
                /* send end of acquisition */
                async->events |= COMEDI_CB_EOA;
@@ -879,229 +1593,238 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
 
        if (!dev->attached)
                return IRQ_NONE;
-       /*  lock to avoid race with comedi_poll */
+       /* lock to avoid race with comedi_poll */
        spin_lock_irqsave(&dev->spinlock, flags);
 
        /* save interrupt enable register state */
-       irqstatus = readl(devpriv->mmio + P_IER);
+       irqstatus = readl(devpriv->mmio + S626_P_IER);
 
        /* read interrupt type */
-       irqtype = readl(devpriv->mmio + P_ISR);
+       irqtype = readl(devpriv->mmio + S626_P_ISR);
 
        /* disable master interrupt */
-       writel(0, devpriv->mmio + P_IER);
+       writel(0, devpriv->mmio + S626_P_IER);
 
        /* clear interrupt */
-       writel(irqtype, devpriv->mmio + P_ISR);
+       writel(irqtype, devpriv->mmio + S626_P_ISR);
 
        switch (irqtype) {
-       case IRQ_RPS1:          /*  end_of_scan occurs */
-               if (handle_eos_interrupt(dev))
+       case S626_IRQ_RPS1:     /* end_of_scan occurs */
+               if (s626_handle_eos_interrupt(dev))
                        irqstatus = 0;
                break;
-       case IRQ_GPIO3: /* check dio and conter interrupt */
+       case S626_IRQ_GPIO3:    /* check dio and counter interrupt */
                /* s626_dio_clear_irq(dev); */
-               check_dio_interrupts(dev);
-               check_counter_interrupts(dev);
+               s626_check_dio_interrupts(dev);
+               s626_check_counter_interrupts(dev);
                break;
        }
 
        /* enable interrupt */
-       writel(irqstatus, devpriv->mmio + P_IER);
+       writel(irqstatus, devpriv->mmio + S626_P_IER);
 
        spin_unlock_irqrestore(&dev->spinlock, flags);
        return IRQ_HANDLED;
 }
 
 /*
- * this functions build the RPS program for hardware driven acquistion
+ * This function builds the RPS program for hardware driven acquisition.
  */
-static void ResetADC(struct comedi_device *dev, uint8_t *ppl)
+static void s626_reset_adc(struct comedi_device *dev, uint8_t *ppl)
 {
        struct s626_private *devpriv = dev->private;
-       register uint32_t *pRPS;
-       uint32_t JmpAdrs;
+       uint32_t *rps;
+       uint32_t jmp_adrs;
        uint16_t i;
        uint16_t n;
-       uint32_t LocalPPL;
-       struct comedi_cmd *cmd = &(dev->subdevices->async->cmd);
+       uint32_t local_ppl;
+       struct comedi_cmd *cmd = &dev->subdevices->async->cmd;
 
        /* Stop RPS program in case it is currently running */
-       s626_mc_disable(dev, MC1_ERPS1, P_MC1);
+       s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1);
 
-       /*  Set starting logical address to write RPS commands. */
-       pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase;
+       /* Set starting logical address to write RPS commands. */
+       rps = (uint32_t *)devpriv->rps_buf.logical_base;
 
        /* Initialize RPS instruction pointer */
-       writel((uint32_t)devpriv->RPSBuf.PhysicalBase,
-              devpriv->mmio + P_RPSADDR1);
-
-       /*  Construct RPS program in RPSBuf DMA buffer */
+       writel((uint32_t)devpriv->rps_buf.physical_base,
+              devpriv->mmio + S626_P_RPSADDR1);
 
+       /* Construct RPS program in rps_buf DMA buffer */
        if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) {
-               /*  Wait for Start trigger. */
-               *pRPS++ = RPS_PAUSE | RPS_SIGADC;
-               *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
+               /* Wait for Start trigger. */
+               *rps++ = S626_RPS_PAUSE | S626_RPS_SIGADC;
+               *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_SIGADC;
        }
 
-       /* SAA7146 BUG WORKAROUND Do a dummy DEBI Write.  This is necessary
+       /*
+        * SAA7146 BUG WORKAROUND Do a dummy DEBI Write.  This is necessary
         * because the first RPS DEBI Write following a non-RPS DEBI write
         * seems to always fail.  If we don't do this dummy write, the ADC
         * gain might not be set to the value required for the first slot in
         * the poll list; the ADC gain would instead remain unchanged from
         * the previously programmed value.
         */
-       *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
        /* Write DEBI Write command and address to shadow RAM. */
+       *rps++ = S626_RPS_LDREG | (S626_P_DEBICMD >> 2);
+       *rps++ = S626_DEBI_CMD_WRWORD | S626_LP_GSEL;
+       *rps++ = S626_RPS_LDREG | (S626_P_DEBIAD >> 2);
+       /* Write DEBI immediate data  to shadow RAM: */
+       *rps++ = S626_GSEL_BIPOLAR5V;   /* arbitrary immediate data  value. */
+       *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_DEBI;
+       /* Reset "shadow RAM  uploaded" flag. */
+       /* Invoke shadow RAM upload. */
+       *rps++ = S626_RPS_UPLOAD | S626_RPS_DEBI;
+       /* Wait for shadow upload to finish. */
+       *rps++ = S626_RPS_PAUSE | S626_RPS_DEBI;
 
-       *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
-       *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
-       /*  Write DEBI immediate data  to shadow RAM: */
-
-       *pRPS++ = GSEL_BIPOLAR5V;
-       /*  arbitrary immediate data  value. */
-
-       *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
-       /*  Reset "shadow RAM  uploaded" flag. */
-       *pRPS++ = RPS_UPLOAD | RPS_DEBI;        /*  Invoke shadow RAM upload. */
-       *pRPS++ = RPS_PAUSE | RPS_DEBI; /*  Wait for shadow upload to finish. */
-
-       /* Digitize all slots in the poll list. This is implemented as a
+       /*
+        * Digitize all slots in the poll list. This is implemented as a
         * for loop to limit the slot count to 16 in case the application
-        * forgot to set the EOPL flag in the final slot.
+        * forgot to set the S626_EOPL flag in the final slot.
         */
-       for (devpriv->AdcItems = 0; devpriv->AdcItems < 16; devpriv->AdcItems++) {
-               /* Convert application's poll list item to private board class
+       for (devpriv->adc_items = 0; devpriv->adc_items < 16;
+            devpriv->adc_items++) {
+               /*
+                * Convert application's poll list item to private board class
                 * format.  Each app poll list item is an uint8_t with form
                 * (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 =
                 * +-10V, 1 = +-5V, and EOPL = End of Poll List marker.
                 */
-               LocalPPL =
-                   (*ppl << 8) | (*ppl & 0x10 ? GSEL_BIPOLAR5V :
-                                  GSEL_BIPOLAR10V);
-
-               /*  Switch ADC analog gain. */
-               *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); /*  Write DEBI command */
-               /*  and address to */
-               /*  shadow RAM. */
-               *pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
-               *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);  /*  Write DEBI */
-               /*  immediate data to */
-               /*  shadow RAM. */
-               *pRPS++ = LocalPPL;
-               *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;     /*  Reset "shadow RAM uploaded" */
-               /*  flag. */
-               *pRPS++ = RPS_UPLOAD | RPS_DEBI;        /*  Invoke shadow RAM upload. */
-               *pRPS++ = RPS_PAUSE | RPS_DEBI; /*  Wait for shadow upload to */
-               /*  finish. */
-
-               /*  Select ADC analog input channel. */
-               *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
-               /*  Write DEBI command and address to  shadow RAM. */
-               *pRPS++ = DEBI_CMD_WRWORD | LP_ISEL;
-               *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
-               /*  Write DEBI immediate data to shadow RAM. */
-               *pRPS++ = LocalPPL;
-               *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
-               /*  Reset "shadow RAM uploaded"  flag. */
-
-               *pRPS++ = RPS_UPLOAD | RPS_DEBI;
-               /*  Invoke shadow RAM upload. */
-
-               *pRPS++ = RPS_PAUSE | RPS_DEBI;
-               /*  Wait for shadow upload to finish. */
-
-               /* Delay at least 10 microseconds for analog input settling.
-                * Instead of padding with NOPs, we use RPS_JUMP instructions
-                * here; this allows us to produce a longer delay than is
-                * possible with NOPs because each RPS_JUMP flushes the RPS'
-                * instruction prefetch pipeline.
+               local_ppl = (*ppl << 8) | (*ppl & 0x10 ? S626_GSEL_BIPOLAR5V :
+                                          S626_GSEL_BIPOLAR10V);
+
+               /* Switch ADC analog gain. */
+               /* Write DEBI command and address to shadow RAM. */
+               *rps++ = S626_RPS_LDREG | (S626_P_DEBICMD >> 2);
+               *rps++ = S626_DEBI_CMD_WRWORD | S626_LP_GSEL;
+               /* Write DEBI immediate data to shadow RAM. */
+               *rps++ = S626_RPS_LDREG | (S626_P_DEBIAD >> 2);
+               *rps++ = local_ppl;
+               /* Reset "shadow RAM uploaded" flag. */
+               *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_DEBI;
+               /* Invoke shadow RAM upload. */
+               *rps++ = S626_RPS_UPLOAD | S626_RPS_DEBI;
+               /* Wait for shadow upload to finish. */
+               *rps++ = S626_RPS_PAUSE | S626_RPS_DEBI;
+               /* Select ADC analog input channel. */
+               *rps++ = S626_RPS_LDREG | (S626_P_DEBICMD >> 2);
+               /* Write DEBI command and address to shadow RAM. */
+               *rps++ = S626_DEBI_CMD_WRWORD | S626_LP_ISEL;
+               *rps++ = S626_RPS_LDREG | (S626_P_DEBIAD >> 2);
+               /* Write DEBI immediate data to shadow RAM. */
+               *rps++ = local_ppl;
+               /* Reset "shadow RAM uploaded" flag. */
+               *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_DEBI;
+               /* Invoke shadow RAM upload. */
+               *rps++ = S626_RPS_UPLOAD | S626_RPS_DEBI;
+               /* Wait for shadow upload to finish. */
+               *rps++ = S626_RPS_PAUSE | S626_RPS_DEBI;
+
+               /*
+                * Delay at least 10 microseconds for analog input settling.
+                * Instead of padding with NOPs, we use S626_RPS_JUMP
+                * instructions here; this allows us to produce a longer delay
+                * than is possible with NOPs because each S626_RPS_JUMP
+                * flushes the RPS' instruction prefetch pipeline.
                 */
-               JmpAdrs =
-                   (uint32_t) devpriv->RPSBuf.PhysicalBase +
-                   (uint32_t) ((unsigned long)pRPS -
-                               (unsigned long)devpriv->RPSBuf.LogicalBase);
-               for (i = 0; i < (10 * RPSCLK_PER_US / 2); i++) {
-                       JmpAdrs += 8;   /*  Repeat to implement time delay: */
-                       *pRPS++ = RPS_JUMP;     /*  Jump to next RPS instruction. */
-                       *pRPS++ = JmpAdrs;
+               jmp_adrs =
+                       (uint32_t)devpriv->rps_buf.physical_base +
+                       (uint32_t)((unsigned long)rps -
+                                  (unsigned long)devpriv->
+                                                 rps_buf.logical_base);
+               for (i = 0; i < (10 * S626_RPSCLK_PER_US / 2); i++) {
+                       jmp_adrs += 8;  /* Repeat to implement time delay: */
+                       /* Jump to next RPS instruction. */
+                       *rps++ = S626_RPS_JUMP;
+                       *rps++ = jmp_adrs;
                }
 
                if (cmd != NULL && cmd->convert_src != TRIG_NOW) {
-                       /*  Wait for Start trigger. */
-                       *pRPS++ = RPS_PAUSE | RPS_SIGADC;
-                       *pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
+                       /* Wait for Start trigger. */
+                       *rps++ = S626_RPS_PAUSE | S626_RPS_SIGADC;
+                       *rps++ = S626_RPS_CLRSIGNAL | S626_RPS_SIGADC;
                }
-               /*  Start ADC by pulsing GPIO1. */
-               *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  Begin ADC Start pulse. */
-               *pRPS++ = GPIO_BASE | GPIO1_LO;
-               *pRPS++ = RPS_NOP;
-               /*  VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
-               *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  End ADC Start pulse. */
-               *pRPS++ = GPIO_BASE | GPIO1_HI;
-
-               /* Wait for ADC to complete (GPIO2 is asserted high when ADC not
+               /* Start ADC by pulsing GPIO1. */
+               /* Begin ADC Start pulse. */
+               *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2);
+               *rps++ = S626_GPIO_BASE | S626_GPIO1_LO;
+               *rps++ = S626_RPS_NOP;
+               /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
+               /* End ADC Start pulse. */
+               *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2);
+               *rps++ = S626_GPIO_BASE | S626_GPIO1_HI;
+               /*
+                * Wait for ADC to complete (GPIO2 is asserted high when ADC not
                 * busy) and for data from previous conversion to shift into FB
                 * BUFFER 1 register.
                 */
-               *pRPS++ = RPS_PAUSE | RPS_GPIO2;        /*  Wait for ADC done. */
-
-               /*  Transfer ADC data from FB BUFFER 1 register to DMA buffer. */
-               *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);
-               *pRPS++ =
-                   (uint32_t) devpriv->ANABuf.PhysicalBase +
-                   (devpriv->AdcItems << 2);
-
-               /*  If this slot's EndOfPollList flag is set, all channels have */
-               /*  now been processed. */
-               if (*ppl++ & EOPL) {
-                       devpriv->AdcItems++;    /*  Adjust poll list item count. */
-                       break;  /*  Exit poll list processing loop. */
+               /* Wait for ADC done. */
+               *rps++ = S626_RPS_PAUSE | S626_RPS_GPIO2;
+
+               /* Transfer ADC data from FB BUFFER 1 register to DMA buffer. */
+               *rps++ = S626_RPS_STREG |
+                        (S626_BUGFIX_STREG(S626_P_FB_BUFFER1) >> 2);
+               *rps++ = (uint32_t)devpriv->ana_buf.physical_base +
+                        (devpriv->adc_items << 2);
+
+               /*
+                * If this slot's EndOfPollList flag is set, all channels have
+                * now been processed.
+                */
+               if (*ppl++ & S626_EOPL) {
+                       devpriv->adc_items++; /* Adjust poll list item count. */
+                       break;  /* Exit poll list processing loop. */
                }
        }
 
-       /* VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US.  Allow the
+       /*
+        * VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US.  Allow the
         * ADC to stabilize for 2 microseconds before starting the final
         * (dummy) conversion.  This delay is necessary to allow sufficient
         * time between last conversion finished and the start of the dummy
         * conversion.  Without this delay, the last conversion's data value
         * is sometimes set to the previous conversion's data value.
         */
-       for (n = 0; n < (2 * RPSCLK_PER_US); n++)
-               *pRPS++ = RPS_NOP;
+       for (n = 0; n < (2 * S626_RPSCLK_PER_US); n++)
+               *rps++ = S626_RPS_NOP;
 
-       /* Start a dummy conversion to cause the data from the last
+       /*
+        * Start a dummy conversion to cause the data from the last
         * conversion of interest to be shifted in.
         */
-       *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  Begin ADC Start pulse. */
-       *pRPS++ = GPIO_BASE | GPIO1_LO;
-       *pRPS++ = RPS_NOP;
+       /* Begin ADC Start pulse. */
+       *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2);
+       *rps++ = S626_GPIO_BASE | S626_GPIO1_LO;
+       *rps++ = S626_RPS_NOP;
        /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
-       *pRPS++ = RPS_LDREG | (P_GPIO >> 2);    /*  End ADC Start pulse. */
-       *pRPS++ = GPIO_BASE | GPIO1_HI;
+       *rps++ = S626_RPS_LDREG | (S626_P_GPIO >> 2); /* End ADC Start pulse. */
+       *rps++ = S626_GPIO_BASE | S626_GPIO1_HI;
 
-       /* Wait for the data from the last conversion of interest to arrive
+       /*
+        * Wait for the data from the last conversion of interest to arrive
         * in FB BUFFER 1 register.
         */
-       *pRPS++ = RPS_PAUSE | RPS_GPIO2;        /*  Wait for ADC done. */
+       *rps++ = S626_RPS_PAUSE | S626_RPS_GPIO2;       /* Wait for ADC done. */
 
-       /*  Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */
-       *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);        /*  */
-       *pRPS++ =
-           (uint32_t) devpriv->ANABuf.PhysicalBase + (devpriv->AdcItems << 2);
+       /* Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */
+       *rps++ = S626_RPS_STREG | (S626_BUGFIX_STREG(S626_P_FB_BUFFER1) >> 2);
+       *rps++ = (uint32_t)devpriv->ana_buf.physical_base +
+                (devpriv->adc_items << 2);
 
-       /*  Indicate ADC scan loop is finished. */
-       /*  *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ;  // Signal ReadADC() that scan is done. */
+       /* Indicate ADC scan loop is finished. */
+       /* Signal ReadADC() that scan is done. */
+       /* *rps++= S626_RPS_CLRSIGNAL | S626_RPS_SIGADC; */
 
        /* invoke interrupt */
-       if (devpriv->ai_cmd_running == 1) {
-               *pRPS++ = RPS_IRQ;
-       }
-       /*  Restart RPS program at its beginning. */
-       *pRPS++ = RPS_JUMP;     /*  Branch to start of RPS program. */
-       *pRPS++ = (uint32_t) devpriv->RPSBuf.PhysicalBase;
+       if (devpriv->ai_cmd_running == 1)
+               *rps++ = S626_RPS_IRQ;
 
-       /*  End of RPS program build */
+       /* Restart RPS program at its beginning. */
+       *rps++ = S626_RPS_JUMP; /* Branch to start of RPS program. */
+       *rps++ = (uint32_t)devpriv->rps_buf.physical_base;
+
+       /* End of RPS program build */
 }
 
 #ifdef unused_code
@@ -1111,14 +1834,14 @@ static int s626_ai_rinsn(struct comedi_device *dev,
                         unsigned int *data)
 {
        struct s626_private *devpriv = dev->private;
-       register uint8_t i;
-       register int32_t *readaddr;
+       uint8_t i;
+       int32_t *readaddr;
 
        /* Trigger ADC scan loop start */
-       s626_mc_enable(dev, MC2_ADC_RPS, P_MC2);
+       s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2);
 
        /* Wait until ADC scan loop is finished (RPS Signal 0 reset) */
-       while (s626_mc_test(dev, MC2_ADC_RPS, P_MC2))
+       while (s626_mc_test(dev, S626_MC2_ADC_RPS, S626_P_MC2))
                ;
 
        /*
@@ -1126,13 +1849,13 @@ static int s626_ai_rinsn(struct comedi_device *dev,
         * first uint16_t in the buffer because it contains junk data from
         * the final ADC of the previous poll list scan.
         */
-       readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1;
+       readaddr = (uint32_t *)devpriv->ana_buf.logical_base + 1;
 
        /*
         * Convert ADC data to 16-bit integer values and
         * copy to application buffer.
         */
-       for (i = 0; i < devpriv->AdcItems; i++) {
+       for (i = 0; i < devpriv->adc_items; i++) {
                *data = s626_ai_reg_to_uint(*readaddr++);
                data++;
        }
@@ -1148,55 +1871,61 @@ static int s626_ai_insn_read(struct comedi_device *dev,
        struct s626_private *devpriv = dev->private;
        uint16_t chan = CR_CHAN(insn->chanspec);
        uint16_t range = CR_RANGE(insn->chanspec);
-       uint16_t AdcSpec = 0;
-       uint32_t GpioImage;
-       int tmp;
+       uint16_t adc_spec = 0;
+       uint32_t gpio_image;
+       uint32_t tmp;
        int n;
 
-       /* Convert application's ADC specification into form
+       /*
+        * Convert application's ADC specification into form
         *  appropriate for register programming.
         */
        if (range == 0)
-               AdcSpec = (chan << 8) | (GSEL_BIPOLAR5V);
+               adc_spec = (chan << 8) | (S626_GSEL_BIPOLAR5V);
        else
-               AdcSpec = (chan << 8) | (GSEL_BIPOLAR10V);
+               adc_spec = (chan << 8) | (S626_GSEL_BIPOLAR10V);
 
-       /*  Switch ADC analog gain. */
-       DEBIwrite(dev, LP_GSEL, AdcSpec);       /*  Set gain. */
+       /* Switch ADC analog gain. */
+       s626_debi_write(dev, S626_LP_GSEL, adc_spec);   /* Set gain. */
 
-       /*  Select ADC analog input channel. */
-       DEBIwrite(dev, LP_ISEL, AdcSpec);       /*  Select channel. */
+       /* Select ADC analog input channel. */
+       s626_debi_write(dev, S626_LP_ISEL, adc_spec);   /* Select channel. */
 
        for (n = 0; n < insn->n; n++) {
-
-               /*  Delay 10 microseconds for analog input settling. */
+               /* Delay 10 microseconds for analog input settling. */
                udelay(10);
 
                /* Start ADC by pulsing GPIO1 low */
-               GpioImage = readl(devpriv->mmio + P_GPIO);
+               gpio_image = readl(devpriv->mmio + S626_P_GPIO);
                /* Assert ADC Start command */
-               writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+               writel(gpio_image & ~S626_GPIO1_HI,
+                      devpriv->mmio + S626_P_GPIO);
                /* and stretch it out */
-               writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
-               writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+               writel(gpio_image & ~S626_GPIO1_HI,
+                      devpriv->mmio + S626_P_GPIO);
+               writel(gpio_image & ~S626_GPIO1_HI,
+                      devpriv->mmio + S626_P_GPIO);
                /* Negate ADC Start command */
-               writel(GpioImage | GPIO1_HI, devpriv->mmio + P_GPIO);
+               writel(gpio_image | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
 
-               /*  Wait for ADC to complete (GPIO2 is asserted high when */
-               /*  ADC not busy) and for data from previous conversion to */
-               /*  shift into FB BUFFER 1 register. */
+               /*
+                * Wait for ADC to complete (GPIO2 is asserted high when
+                * ADC not busy) and for data from previous conversion to
+                * shift into FB BUFFER 1 register.
+                */
 
                /* Wait for ADC done */
-               while (!(readl(devpriv->mmio + P_PSR) & PSR_GPIO2))
+               while (!(readl(devpriv->mmio + S626_P_PSR) & S626_PSR_GPIO2))
                        ;
 
                /* Fetch ADC data */
                if (n != 0) {
-                       tmp = readl(devpriv->mmio + P_FB_BUFFER1);
+                       tmp = readl(devpriv->mmio + S626_P_FB_BUFFER1);
                        data[n - 1] = s626_ai_reg_to_uint(tmp);
                }
 
-               /* Allow the ADC to stabilize for 4 microseconds before
+               /*
+                * Allow the ADC to stabilize for 4 microseconds before
                 * starting the next (final) conversion.  This delay is
                 * necessary to allow sufficient time between last
                 * conversion finished and the start of the next
@@ -1207,28 +1936,30 @@ static int s626_ai_insn_read(struct comedi_device *dev,
                udelay(4);
        }
 
-       /* Start a dummy conversion to cause the data from the
-        * previous conversion to be shifted in. */
-       GpioImage = readl(devpriv->mmio + P_GPIO);
+       /*
+        * Start a dummy conversion to cause the data from the
+        * previous conversion to be shifted in.
+        */
+       gpio_image = readl(devpriv->mmio + S626_P_GPIO);
        /* Assert ADC Start command */
-       writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+       writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
        /* and stretch it out */
-       writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
-       writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO);
+       writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
+       writel(gpio_image & ~S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
        /* Negate ADC Start command */
-       writel(GpioImage | GPIO1_HI, devpriv->mmio + P_GPIO);
+       writel(gpio_image | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
 
-       /*  Wait for the data to arrive in FB BUFFER 1 register. */
+       /* Wait for the data to arrive in FB BUFFER 1 register. */
 
        /* Wait for ADC done */
-       while (!(readl(devpriv->mmio + P_PSR) & PSR_GPIO2))
+       while (!(readl(devpriv->mmio + S626_P_PSR) & S626_PSR_GPIO2))
                ;
 
-       /*  Fetch ADC data from audio interface's input shift register. */
+       /* Fetch ADC data from audio interface's input shift register. */
 
        /* Fetch ADC data */
        if (n != 0) {
-               tmp = readl(devpriv->mmio + P_FB_BUFFER1);
+               tmp = readl(devpriv->mmio + S626_P_FB_BUFFER1);
                data[n - 1] = s626_ai_reg_to_uint(tmp);
        }
 
@@ -1237,17 +1968,16 @@ static int s626_ai_insn_read(struct comedi_device *dev,
 
 static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
 {
-
        int n;
 
        for (n = 0; n < cmd->chanlist_len; n++) {
-               if (CR_RANGE((cmd->chanlist)[n]) == 0)
-                       ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_5V);
+               if (CR_RANGE(cmd->chanlist[n]) == 0)
+                       ppl[n] = CR_CHAN(cmd->chanlist[n]) | S626_RANGE_5V;
                else
-                       ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_10V);
+                       ppl[n] = CR_CHAN(cmd->chanlist[n]) | S626_RANGE_10V;
        }
        if (n != 0)
-               ppl[n - 1] |= EOPL;
+               ppl[n - 1] |= S626_EOPL;
 
        return n;
 }
@@ -1259,18 +1989,20 @@ static int s626_ai_inttrig(struct comedi_device *dev,
                return -EINVAL;
 
        /* Start executing the RPS program */
-       s626_mc_enable(dev, MC1_ERPS1, P_MC1);
+       s626_mc_enable(dev, S626_MC1_ERPS1, S626_P_MC1);
 
        s->async->inttrig = NULL;
 
        return 1;
 }
 
-/* This function doesn't require a particular form, this is just what
+/*
+ * This function doesn't require a particular form, this is just what
  * happens to be used in some of the drivers.  It should convert ns
  * nanoseconds to a counter value suitable for programming the device.
  * Also, it should adjust ns so that it cooresponds to the actual time
- * that the device will use. */
+ * that the device will use.
+ */
 static int s626_ns_to_timer(int *nanosec, int round_mode)
 {
        int divider, base;
@@ -1294,68 +2026,74 @@ static int s626_ns_to_timer(int *nanosec, int round_mode)
        return divider - 1;
 }
 
-static void s626_timer_load(struct comedi_device *dev, struct enc_private *k,
-                           int tick)
+static void s626_timer_load(struct comedi_device *dev,
+                           const struct s626_enc_info *k, int tick)
 {
-       uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /*  Preload upon */
-           /*  index. */
-           (INDXSRC_SOFT << BF_INDXSRC) |      /*  Disable hardware index. */
-           (CLKSRC_TIMER << BF_CLKSRC) |       /*  Operating mode is Timer. */
-           (CLKPOL_POS << BF_CLKPOL) | /*  Active high clock. */
-           (CNTDIR_DOWN << BF_CLKPOL) |        /*  Count direction is Down. */
-           (CLKMULT_1X << BF_CLKMULT) |        /*  Clock multiplier is 1x. */
-           (CLKENAB_INDEX << BF_CLKENAB);
-       uint16_t valueSrclatch = LATCHSRC_A_INDXA;
-       /*   uint16_t enab=CLKENAB_ALWAYS; */
+       uint16_t setup =
+               /* Preload upon index. */
+               (S626_LOADSRC_INDX << S626_BF_LOADSRC) |
+               /* Disable hardware index. */
+               (S626_INDXSRC_SOFT << S626_BF_INDXSRC) |
+               /* Operating mode is Timer. */
+               (S626_ENCMODE_TIMER << S626_BF_ENCMODE) |
+               /* Count direction is Down. */
+               (S626_CNTDIR_DOWN << S626_BF_CLKPOL) |
+               /* Clock multiplier is 1x. */
+               (S626_CLKMULT_1X << S626_BF_CLKMULT) |
+               (S626_CLKENAB_INDEX << S626_BF_CLKENAB);
+       uint16_t value_latchsrc = S626_LATCHSRC_A_INDXA;
+       /* uint16_t enab = S626_CLKENAB_ALWAYS; */
 
-       k->SetMode(dev, k, Setup, FALSE);
+       k->set_mode(dev, k, setup, false);
 
-       /*  Set the preload register */
-       Preload(dev, k, tick);
+       /* Set the preload register */
+       s626_preload(dev, k, tick);
 
-       /*  Software index pulse forces the preload register to load */
-       /*  into the counter */
-       k->SetLoadTrig(dev, k, 0);
-       k->PulseIndex(dev, k);
+       /*
+        * Software index pulse forces the preload register to load
+        * into the counter
+        */
+       k->set_load_trig(dev, k, 0);
+       k->pulse_index(dev, k);
 
        /* set reload on counter overflow */
-       k->SetLoadTrig(dev, k, 1);
+       k->set_load_trig(dev, k, 1);
 
        /* set interrupt on overflow */
-       k->SetIntSrc(dev, k, INTSRC_OVER);
+       k->set_int_src(dev, k, S626_INTSRC_OVER);
 
-       SetLatchSource(dev, k, valueSrclatch);
-       /*   k->SetEnable(dev,k,(uint16_t)(enab != 0)); */
+       s626_set_latch_source(dev, k, value_latchsrc);
+       /* k->set_enable(dev, k, (uint16_t)(enab != 0)); */
 }
 
-/*  TO COMPLETE  */
+/* TO COMPLETE  */
 static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        struct s626_private *devpriv = dev->private;
        uint8_t ppl[16];
        struct comedi_cmd *cmd = &s->async->cmd;
-       struct enc_private *k;
+       const struct s626_enc_info *k;
        int tick;
 
        if (devpriv->ai_cmd_running) {
-               printk(KERN_ERR "s626_ai_cmd: Another ai_cmd is running %d\n",
-                      dev->minor);
+               dev_err(dev->class_dev,
+                       "s626_ai_cmd: Another ai_cmd is running\n");
                return -EBUSY;
        }
        /* disable interrupt */
-       writel(0, devpriv->mmio + P_IER);
+       writel(0, devpriv->mmio + S626_P_IER);
 
        /* clear interrupt request */
-       writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->mmio + P_ISR);
+       writel(S626_IRQ_RPS1 | S626_IRQ_GPIO3, devpriv->mmio + S626_P_ISR);
 
        /* clear any pending interrupt */
        s626_dio_clear_irq(dev);
-       /*   s626_enc_clear_irq(dev); */
+       /* s626_enc_clear_irq(dev); */
 
        /* reset ai_cmd_running flag */
        devpriv->ai_cmd_running = 0;
 
-       /*  test if cmd is valid */
+       /* test if cmd is valid */
        if (cmd == NULL)
                return -EINVAL;
 
@@ -1373,17 +2111,20 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        case TRIG_FOLLOW:
                break;
        case TRIG_TIMER:
-               /*  set a conter to generate adc trigger at scan_begin_arg interval */
-               k = &encpriv[5];
+               /*
+                * set a counter to generate adc trigger at scan_begin_arg
+                * interval
+                */
+               k = &s626_enc_chan_info[5];
                tick = s626_ns_to_timer((int *)&cmd->scan_begin_arg,
                                        cmd->flags & TRIG_ROUND_MASK);
 
                /* load timer value and enable interrupt */
                s626_timer_load(dev, k, tick);
-               k->SetEnable(dev, k, CLKENAB_ALWAYS);
+               k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
                break;
        case TRIG_EXT:
-               /*  set the digital line and interrupt for scan trigger */
+               /* set the digital line and interrupt for scan trigger */
                if (cmd->start_src != TRIG_EXT)
                        s626_dio_set_irq(dev, cmd->scan_begin_arg);
                break;
@@ -1393,52 +2134,53 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        case TRIG_NOW:
                break;
        case TRIG_TIMER:
-               /*  set a conter to generate adc trigger at convert_arg interval */
-               k = &encpriv[4];
+               /*
+                * set a counter to generate adc trigger at convert_arg
+                * interval
+                */
+               k = &s626_enc_chan_info[4];
                tick = s626_ns_to_timer((int *)&cmd->convert_arg,
                                        cmd->flags & TRIG_ROUND_MASK);
 
                /* load timer value and enable interrupt */
                s626_timer_load(dev, k, tick);
-               k->SetEnable(dev, k, CLKENAB_INDEX);
+               k->set_enable(dev, k, S626_CLKENAB_INDEX);
                break;
        case TRIG_EXT:
-               /*  set the digital line and interrupt for convert trigger */
-               if (cmd->scan_begin_src != TRIG_EXT
-                   && cmd->start_src == TRIG_EXT)
+               /* set the digital line and interrupt for convert trigger */
+               if (cmd->scan_begin_src != TRIG_EXT &&
+                   cmd->start_src == TRIG_EXT)
                        s626_dio_set_irq(dev, cmd->convert_arg);
                break;
        }
 
        switch (cmd->stop_src) {
        case TRIG_COUNT:
-               /*  data arrives as one packet */
+               /* data arrives as one packet */
                devpriv->ai_sample_count = cmd->stop_arg;
-               devpriv->ai_continous = 0;
+               devpriv->ai_continuous = 0;
                break;
        case TRIG_NONE:
-               /*  continous acquisition */
-               devpriv->ai_continous = 1;
+               /* continuous acquisition */
+               devpriv->ai_continuous = 1;
                devpriv->ai_sample_count = 1;
                break;
        }
 
-       ResetADC(dev, ppl);
+       s626_reset_adc(dev, ppl);
 
        switch (cmd->start_src) {
        case TRIG_NOW:
                /* Trigger ADC scan loop start */
-               /* s626_mc_enable(dev, MC2_ADC_RPS, P_MC2); */
+               /* s626_mc_enable(dev, S626_MC2_ADC_RPS, S626_P_MC2); */
 
                /* Start executing the RPS program */
-               s626_mc_enable(dev, MC1_ERPS1, P_MC1);
-
+               s626_mc_enable(dev, S626_MC1_ERPS1, S626_P_MC1);
                s->async->inttrig = NULL;
                break;
        case TRIG_EXT:
                /* configure DIO channel for acquisition trigger */
                s626_dio_set_irq(dev, cmd->start_arg);
-
                s->async->inttrig = NULL;
                break;
        case TRIG_INT:
@@ -1447,7 +2189,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        }
 
        /* enable interrupt */
-       writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->mmio + P_IER);
+       writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1, devpriv->mmio + S626_P_IER);
 
        return 0;
 }
@@ -1461,11 +2203,11 @@ static int s626_ai_cmdtest(struct comedi_device *dev,
        /* Step 1 : check if triggers are trivially valid */
 
        err |= cfc_check_trigger_src(&cmd->start_src,
-                                       TRIG_NOW | TRIG_INT | TRIG_EXT);
+                                    TRIG_NOW | TRIG_INT | TRIG_EXT);
        err |= cfc_check_trigger_src(&cmd->scan_begin_src,
-                                       TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW);
+                                    TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW);
        err |= cfc_check_trigger_src(&cmd->convert_src,
-                                       TRIG_TIMER | TRIG_EXT | TRIG_NOW);
+                                    TRIG_TIMER | TRIG_EXT | TRIG_NOW);
        err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
        err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 
@@ -1490,34 +2232,34 @@ static int s626_ai_cmdtest(struct comedi_device *dev,
                err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
        if (cmd->start_src == TRIG_EXT)
                err |= cfc_check_trigger_arg_max(&cmd->start_arg, 39);
-
        if (cmd->scan_begin_src == TRIG_EXT)
                err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 39);
-
        if (cmd->convert_src == TRIG_EXT)
                err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 39);
 
-#define MAX_SPEED      200000  /* in nanoseconds */
-#define MIN_SPEED      2000000000      /* in nanoseconds */
+#define S626_MAX_SPEED 200000  /* in nanoseconds */
+#define S626_MIN_SPEED 2000000000      /* in nanoseconds */
 
        if (cmd->scan_begin_src == TRIG_TIMER) {
                err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
-                                                MAX_SPEED);
+                                                S626_MAX_SPEED);
                err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
-                                                MIN_SPEED);
+                                                S626_MIN_SPEED);
        } else {
                /* external trigger */
                /* should be level/edge, hi/lo specification here */
                /* should specify multiple external triggers */
-/*             err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */
+               /* err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */
        }
        if (cmd->convert_src == TRIG_TIMER) {
-               err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED);
-               err |= cfc_check_trigger_arg_max(&cmd->convert_arg, MIN_SPEED);
+               err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
+                                                S626_MAX_SPEED);
+               err |= cfc_check_trigger_arg_max(&cmd->convert_arg,
+                                                S626_MIN_SPEED);
        } else {
                /* external trigger */
                /* see above */
-/*             err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */
+               /* err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */
        }
 
        err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
@@ -1546,10 +2288,10 @@ static int s626_ai_cmdtest(struct comedi_device *dev,
                if (tmp != cmd->convert_arg)
                        err++;
                if (cmd->scan_begin_src == TRIG_TIMER &&
-                   cmd->scan_begin_arg <
-                   cmd->convert_arg * cmd->scan_end_arg) {
-                       cmd->scan_begin_arg =
-                           cmd->convert_arg * cmd->scan_end_arg;
+                   cmd->scan_begin_arg < cmd->convert_arg *
+                                         cmd->scan_end_arg) {
+                       cmd->scan_begin_arg = cmd->convert_arg *
+                                             cmd->scan_end_arg;
                        err++;
                }
        }
@@ -1565,10 +2307,10 @@ static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
        struct s626_private *devpriv = dev->private;
 
        /* Stop RPS program in case it is currently running */
-       s626_mc_disable(dev, MC1_ERPS1, P_MC1);
+       s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1);
 
        /* disable master interrupt */
-       writel(0, devpriv->mmio + P_IER);
+       writel(0, devpriv->mmio + S626_P_IER);
 
        devpriv->ai_cmd_running = 0;
 
@@ -1588,7 +2330,7 @@ static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
                devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[i];
                dacdata -= (0x1fff);
 
-               SetDAC(dev, chan, dacdata);
+               s626_set_dac(dev, chan, dacdata);
        }
 
        return i;
@@ -1606,7 +2348,9 @@ static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
        return i;
 }
 
-/* *************** DIGITAL I/O FUNCTIONS ***************
+/* *************** DIGITAL I/O FUNCTIONS *************** */
+
+/*
  * All DIO functions address a group of DIO channels by means of
  * "group" argument.  group may be 0, 1 or 2, which correspond to DIO
  * ports A, B and C, respectively.
@@ -1616,19 +2360,19 @@ static void s626_dio_init(struct comedi_device *dev)
 {
        uint16_t group;
 
-       /*  Prepare to treat writes to WRCapSel as capture disables. */
-       DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
+       /* Prepare to treat writes to WRCapSel as capture disables. */
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_NOEDCAP);
 
-       /*  For each group of sixteen channels ... */
+       /* For each group of sixteen channels ... */
        for (group = 0; group < S626_DIO_BANKS; group++) {
                /* Disable all interrupts */
-               DEBIwrite(dev, LP_WRINTSEL(group), 0);
+               s626_debi_write(dev, S626_LP_WRINTSEL(group), 0);
                /* Disable all event captures */
-               DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff);
+               s626_debi_write(dev, S626_LP_WRCAPSEL(group), 0xffff);
                /* Init all DIOs to default edge polarity */
-               DEBIwrite(dev, LP_WREDGSEL(group), 0);
+               s626_debi_write(dev, S626_LP_WREDGSEL(group), 0);
                /* Program all outputs to inactive state */
-               DEBIwrite(dev, LP_WRDOUT(group), 0);
+               s626_debi_write(dev, S626_LP_WRDOUT(group), 0);
        }
 }
 
@@ -1638,20 +2382,11 @@ static int s626_dio_insn_bits(struct comedi_device *dev,
                              unsigned int *data)
 {
        unsigned long group = (unsigned long)s->private;
-       unsigned long mask = data[0];
-       unsigned long bits = data[1];
-
-       if (mask) {
-               /* Check if requested channels are configured for output */
-               if ((s->io_bits & mask) != mask)
-                       return -EIO;
 
-               s->state &= ~mask;
-               s->state |= (bits & mask);
+       if (comedi_dio_update_state(s, data))
+               s626_debi_write(dev, S626_LP_WRDOUT(group), s->state);
 
-               DEBIwrite(dev, LP_WRDOUT(group), s->state);
-       }
-       data[1] = DEBIread(dev, LP_RDDIN(group));
+       data[1] = s626_debi_read(dev, S626_LP_RDDIN(group));
 
        return insn->n;
 }
@@ -1668,42 +2403,50 @@ static int s626_dio_insn_config(struct comedi_device *dev,
        if (ret)
                return ret;
 
-       DEBIwrite(dev, LP_WRDOUT(group), s->io_bits);
+       s626_debi_write(dev, S626_LP_WRDOUT(group), s->io_bits);
 
        return insn->n;
 }
 
-/* Now this function initializes the value of the counter (data[0])
-   and set the subdevice. To complete with trigger and interrupt
-   configuration */
-/* FIXME: data[0] is supposed to be an INSN_CONFIG_xxx constant indicating
+/*
+ * Now this function initializes the value of the counter (data[0])
+ * and set the subdevice. To complete with trigger and interrupt
+ * configuration.
+ *
+ * FIXME: data[0] is supposed to be an INSN_CONFIG_xxx constant indicating
  * what is being configured, but this function appears to be using data[0]
- * as a variable. */
+ * as a variable.
+ */
 static int s626_enc_insn_config(struct comedi_device *dev,
                                struct comedi_subdevice *s,
                                struct comedi_insn *insn, unsigned int *data)
 {
-       uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /*  Preload upon */
-           /*  index. */
-           (INDXSRC_SOFT << BF_INDXSRC) |      /*  Disable hardware index. */
-           (CLKSRC_COUNTER << BF_CLKSRC) |     /*  Operating mode is Counter. */
-           (CLKPOL_POS << BF_CLKPOL) | /*  Active high clock. */
-           /* ( CNTDIR_UP << BF_CLKPOL ) |      // Count direction is Down. */
-           (CLKMULT_1X << BF_CLKMULT) |        /*  Clock multiplier is 1x. */
-           (CLKENAB_INDEX << BF_CLKENAB);
-       /*   uint16_t DisableIntSrc=TRUE; */
-       /*  uint32_t Preloadvalue;              //Counter initial value */
-       uint16_t valueSrclatch = LATCHSRC_AB_READ;
-       uint16_t enab = CLKENAB_ALWAYS;
-       struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
-
-       /*   (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
-
-       k->SetMode(dev, k, Setup, TRUE);
-       Preload(dev, k, data[0]);
-       k->PulseIndex(dev, k);
-       SetLatchSource(dev, k, valueSrclatch);
-       k->SetEnable(dev, k, (uint16_t) (enab != 0));
+       uint16_t setup =
+               /* Preload upon index. */
+               (S626_LOADSRC_INDX << S626_BF_LOADSRC) |
+               /* Disable hardware index. */
+               (S626_INDXSRC_SOFT << S626_BF_INDXSRC) |
+               /* Operating mode is Counter. */
+               (S626_ENCMODE_COUNTER << S626_BF_ENCMODE) |
+               /* Active high clock. */
+               (S626_CLKPOL_POS << S626_BF_CLKPOL) |
+               /* Clock multiplier is 1x. */
+               (S626_CLKMULT_1X << S626_BF_CLKMULT) |
+               (S626_CLKENAB_INDEX << S626_BF_CLKENAB);
+       /* uint16_t disable_int_src = true; */
+       /* uint32_t Preloadvalue;              //Counter initial value */
+       uint16_t value_latchsrc = S626_LATCHSRC_AB_READ;
+       uint16_t enab = S626_CLKENAB_ALWAYS;
+       const struct s626_enc_info *k =
+               &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
+
+       /* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
+
+       k->set_mode(dev, k, setup, true);
+       s626_preload(dev, k, data[0]);
+       k->pulse_index(dev, k);
+       s626_set_latch_source(dev, k, value_latchsrc);
+       k->set_enable(dev, k, (enab != 0));
 
        return insn->n;
 }
@@ -1712,12 +2455,12 @@ static int s626_enc_insn_read(struct comedi_device *dev,
                              struct comedi_subdevice *s,
                              struct comedi_insn *insn, unsigned int *data)
 {
-
        int n;
-       struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+       const struct s626_enc_info *k =
+               &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
 
        for (n = 0; n < insn->n; n++)
-               data[n] = ReadLatch(dev, k);
+               data[n] = s626_read_latch(dev, k);
 
        return n;
 }
@@ -1726,31 +2469,32 @@ static int s626_enc_insn_write(struct comedi_device *dev,
                               struct comedi_subdevice *s,
                               struct comedi_insn *insn, unsigned int *data)
 {
+       const struct s626_enc_info *k =
+               &s626_enc_chan_info[CR_CHAN(insn->chanspec)];
 
-       struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+       /* Set the preload register */
+       s626_preload(dev, k, data[0]);
 
-       /*  Set the preload register */
-       Preload(dev, k, data[0]);
-
-       /*  Software index pulse forces the preload register to load */
-       /*  into the counter */
-       k->SetLoadTrig(dev, k, 0);
-       k->PulseIndex(dev, k);
-       k->SetLoadTrig(dev, k, 2);
+       /*
+        * Software index pulse forces the preload register to load
+        * into the counter
+        */
+       k->set_load_trig(dev, k, 0);
+       k->pulse_index(dev, k);
+       k->set_load_trig(dev, k, 2);
 
        return 1;
 }
 
-static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage)
+static void s626_write_misc2(struct comedi_device *dev, uint16_t new_image)
 {
-       DEBIwrite(dev, LP_MISC1, MISC1_WENABLE);        /*  enab writes to */
-       /*  MISC2 register. */
-       DEBIwrite(dev, LP_WRMISC2, NewImage);   /*  Write new image to MISC2. */
-       DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE);       /*  Disable writes to MISC2. */
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_WENABLE);
+       s626_debi_write(dev, S626_LP_WRMISC2, new_image);
+       s626_debi_write(dev, S626_LP_MISC1, S626_MISC1_WDISABLE);
 }
 
-static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
-                     size_t bsize)
+static void s626_close_dma_b(struct comedi_device *dev,
+                            struct s626_buffer_dma *pdma, size_t bsize)
 {
        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
        void *vbptr;
@@ -1758,554 +2502,44 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
 
        if (pdma == NULL)
                return;
-       /* find the matching allocation from the board struct */
 
-       vbptr = pdma->LogicalBase;
-       vpptr = pdma->PhysicalBase;
+       /* find the matching allocation from the board struct */
+       vbptr = pdma->logical_base;
+       vpptr = pdma->physical_base;
        if (vbptr) {
                pci_free_consistent(pcidev, bsize, vbptr, vpptr);
-               pdma->LogicalBase = NULL;
-               pdma->PhysicalBase = 0;
+               pdma->logical_base = NULL;
+               pdma->physical_base = 0;
        }
 }
 
-/* ******  PRIVATE COUNTER FUNCTIONS ****** */
-
-/*  Reset a counter's index and overflow event capture flags. */
-
-static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k)
-{
-       DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL,
-                   CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
-}
-
-static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k)
-{
-       DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL,
-                   CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B);
-}
-
-/*  Return counter setup in a format (COUNTER_SETUP) that is consistent */
-/*  for both A and B counters. */
-
-static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k)
-{
-       register uint16_t cra;
-       register uint16_t crb;
-       register uint16_t setup;
-
-       /*  Fetch CRA and CRB register images. */
-       cra = DEBIread(dev, k->MyCRA);
-       crb = DEBIread(dev, k->MyCRB);
-
-       /*  Populate the standardized counter setup bit fields.  Note: */
-       /*  IndexSrc is restricted to ENC_X or IndxPol. */
-       setup = ((cra & STDMSK_LOADSRC) /*  LoadSrc  = LoadSrcA. */
-                |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)      /*  LatchSrc = LatchSrcA. */
-                |((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC)  /*  IntSrc   = IntSrcA. */
-                |((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC) /*  IndxSrc  = IndxSrcA<1>. */
-                |((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL)       /*  IndxPol  = IndxPolA. */
-                |((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB));     /*  ClkEnab  = ClkEnabA. */
-
-       /*  Adjust mode-dependent parameters. */
-       if (cra & (2 << CRABIT_CLKSRC_A))       /*  If Timer mode (ClkSrcA<1> == 1): */
-               setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)       /*    Indicate Timer mode. */
-                         |((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL) /*    Set ClkPol to indicate count direction (ClkSrcA<0>). */
-                         |(MULT_X1 << STDBIT_CLKMULT));        /*    ClkMult must be 1x in Timer mode. */
-
-       else                    /*  If Counter mode (ClkSrcA<1> == 0): */
-               setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)     /*    Indicate Counter mode. */
-                         |((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL) /*    Pass through ClkPol. */
-                         |(((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ?       /*    Force ClkMult to 1x if not legal, else pass through. */
-                           (MULT_X1 << STDBIT_CLKMULT) :
-                           ((cra >> (CRABIT_CLKMULT_A -
-                                     STDBIT_CLKMULT)) & STDMSK_CLKMULT)));
-
-       /*  Return adjusted counter setup. */
-       return setup;
-}
-
-static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k)
-{
-       register uint16_t cra;
-       register uint16_t crb;
-       register uint16_t setup;
-
-       /*  Fetch CRA and CRB register images. */
-       cra = DEBIread(dev, k->MyCRA);
-       crb = DEBIread(dev, k->MyCRB);
-
-       /*  Populate the standardized counter setup bit fields.  Note: */
-       /*  IndexSrc is restricted to ENC_X or IndxPol. */
-       setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC)   /*  IntSrc   = IntSrcB. */
-                |((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC)      /*  LatchSrc = LatchSrcB. */
-                |((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC)       /*  LoadSrc  = LoadSrcB. */
-                |((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL)       /*  IndxPol  = IndxPolB. */
-                |((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB)       /*  ClkEnab  = ClkEnabB. */
-                |((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC));       /*  IndxSrc  = IndxSrcB<1>. */
-
-       /*  Adjust mode-dependent parameters. */
-       if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B))  /*  If Extender mode (ClkMultB == MULT_X0): */
-               setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC)    /*    Indicate Extender mode. */
-                         |(MULT_X1 << STDBIT_CLKMULT)  /*    Indicate multiplier is 1x. */
-                         |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));       /*    Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
-
-       else if (cra & (2 << CRABIT_CLKSRC_B))  /*  If Timer mode (ClkSrcB<1> == 1): */
-               setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC)       /*    Indicate Timer mode. */
-                         |(MULT_X1 << STDBIT_CLKMULT)  /*    Indicate multiplier is 1x. */
-                         |((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL));       /*    Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
-
-       else                    /*  If Counter mode (ClkSrcB<1> == 0): */
-               setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC)     /*    Indicate Timer mode. */
-                         |((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT)      /*    Clock multiplier is passed through. */
-                         |((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL));       /*    Clock polarity is passed through. */
-
-       /*  Return adjusted counter setup. */
-       return setup;
-}
-
-/*
- * Set the operating mode for the specified counter.  The setup
- * parameter is treated as a COUNTER_SETUP data type.  The following
- * parameters are programmable (all other parms are ignored): ClkMult,
- * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
- */
-
-static void SetMode_A(struct comedi_device *dev, struct enc_private *k,
-                     uint16_t Setup, uint16_t DisableIntSrc)
-{
-       struct s626_private *devpriv = dev->private;
-       register uint16_t cra;
-       register uint16_t crb;
-       register uint16_t setup = Setup;        /*  Cache the Standard Setup. */
-
-       /*  Initialize CRA and CRB images. */
-       cra = ((setup & CRAMSK_LOADSRC_A)       /*  Preload trigger is passed through. */
-              |((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))));       /*  IndexSrc is restricted to ENC_X or IndxPol. */
-
-       crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A   /*  Reset any pending CounterA event captures. */
-              | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)));    /*  Clock enable is passed through. */
-
-       /*  Force IntSrc to Disabled if DisableIntSrc is asserted. */
-       if (!DisableIntSrc)
-               cra |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
-                                                   CRABIT_INTSRC_A));
-
-       /*  Populate all mode-dependent attributes of CRA & CRB images. */
-       switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
-       case CLKSRC_EXTENDER:   /*  Extender Mode: Force to Timer mode */
-               /*  (Extender valid only for B counters). */
-
-       case CLKSRC_TIMER:      /*  Timer Mode: */
-               cra |= ((2 << CRABIT_CLKSRC_A)  /*    ClkSrcA<1> selects system clock */
-                       |((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) /*      with count direction (ClkSrcA<0>) obtained from ClkPol. */
-                       |(1 << CRABIT_CLKPOL_A) /*    ClkPolA behaves as always-on clock enable. */
-                       |(MULT_X1 << CRABIT_CLKMULT_A));        /*    ClkMult must be 1x. */
-               break;
-
-       default:                /*  Counter Mode: */
-               cra |= (CLKSRC_COUNTER  /*    Select ENC_C and ENC_D as clock/direction inputs. */
-                       | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL))        /*    Clock polarity is passed through. */
-                       |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?   /*    Force multiplier to x1 if not legal, otherwise pass through. */
-                         (MULT_X1 << CRABIT_CLKMULT_A) :
-                         ((setup & STDMSK_CLKMULT) << (CRABIT_CLKMULT_A -
-                                                       STDBIT_CLKMULT))));
-       }
-
-       /*  Force positive index polarity if IndxSrc is software-driven only, */
-       /*  otherwise pass it through. */
-       if (~setup & STDMSK_INDXSRC)
-               cra |= ((setup & STDMSK_INDXPOL) << (CRABIT_INDXPOL_A -
-                                                    STDBIT_INDXPOL));
-
-       /*  If IntSrc has been forced to Disabled, update the MISC2 interrupt */
-       /*  enable mask to indicate the counter interrupt is disabled. */
-       if (DisableIntSrc)
-               devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
-
-       /*  While retaining CounterB and LatchSrc configurations, program the */
-       /*  new counter operating mode. */
-       DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra);
-       DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A), crb);
-}
-
-static void SetMode_B(struct comedi_device *dev, struct enc_private *k,
-                     uint16_t Setup, uint16_t DisableIntSrc)
-{
-       struct s626_private *devpriv = dev->private;
-       register uint16_t cra;
-       register uint16_t crb;
-       register uint16_t setup = Setup;        /*  Cache the Standard Setup. */
-
-       /*  Initialize CRA and CRB images. */
-       cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC));  /*  IndexSrc field is restricted to ENC_X or IndxPol. */
-
-       crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B   /*  Reset event captures and disable interrupts. */
-              | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB))      /*  Clock enable is passed through. */
-              |((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)));     /*  Preload trigger source is passed through. */
-
-       /*  Force IntSrc to Disabled if DisableIntSrc is asserted. */
-       if (!DisableIntSrc)
-               crb |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
-                                                   CRBBIT_INTSRC_B));
-
-       /*  Populate all mode-dependent attributes of CRA & CRB images. */
-       switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
-       case CLKSRC_TIMER:      /*  Timer Mode: */
-               cra |= ((2 << CRABIT_CLKSRC_B)  /*    ClkSrcB<1> selects system clock */
-                       |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));       /*      with direction (ClkSrcB<0>) obtained from ClkPol. */
-               crb |= ((1 << CRBBIT_CLKPOL_B)  /*    ClkPolB behaves as always-on clock enable. */
-                       |(MULT_X1 << CRBBIT_CLKMULT_B));        /*    ClkMultB must be 1x. */
-               break;
-
-       case CLKSRC_EXTENDER:   /*  Extender Mode: */
-               cra |= ((2 << CRABIT_CLKSRC_B)  /*    ClkSrcB source is OverflowA (same as "timer") */
-                       |((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL)));       /*      with direction obtained from ClkPol. */
-               crb |= ((1 << CRBBIT_CLKPOL_B)  /*    ClkPolB controls IndexB -- always set to active. */
-                       |(MULT_X0 << CRBBIT_CLKMULT_B));        /*    ClkMultB selects OverflowA as the clock source. */
-               break;
-
-       default:                /*  Counter Mode: */
-               cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B);     /*    Select ENC_C and ENC_D as clock/direction inputs. */
-               crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B))  /*    ClkPol is passed through. */
-                       |(((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ?   /*    Force ClkMult to x1 if not legal, otherwise pass through. */
-                         (MULT_X1 << CRBBIT_CLKMULT_B) :
-                         ((setup & STDMSK_CLKMULT) << (CRBBIT_CLKMULT_B -
-                                                       STDBIT_CLKMULT))));
-       }
-
-       /*  Force positive index polarity if IndxSrc is software-driven only, */
-       /*  otherwise pass it through. */
-       if (~setup & STDMSK_INDXSRC)
-               crb |= ((setup & STDMSK_INDXPOL) >> (STDBIT_INDXPOL -
-                                                    CRBBIT_INDXPOL_B));
-
-       /*  If IntSrc has been forced to Disabled, update the MISC2 interrupt */
-       /*  enable mask to indicate the counter interrupt is disabled. */
-       if (DisableIntSrc)
-               devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
-
-       /*  While retaining CounterA and LatchSrc configurations, program the */
-       /*  new counter operating mode. */
-       DEBIreplace(dev, k->MyCRA, ~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B), cra);
-       DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb);
-}
-
-/*  Return/set a counter's enable.  enab: 0=always enabled, 1=enabled by index. */
-
-static void SetEnable_A(struct comedi_device *dev, struct enc_private *k,
-                       uint16_t enab)
-{
-       DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A),
-                   enab << CRBBIT_CLKENAB_A);
-}
-
-static void SetEnable_B(struct comedi_device *dev, struct enc_private *k,
-                       uint16_t enab)
-{
-       DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B),
-                   enab << CRBBIT_CLKENAB_B);
-}
-
-static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_A) & 1;
-}
-
-static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_B) & 1;
-}
-
-/*
- * static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k )
- * {
- *     return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3;
- * }
- */
-
-/*
- * Return/set the event that will trigger transfer of the preload
- * register into the counter.  0=ThisCntr_Index, 1=ThisCntr_Overflow,
- * 2=OverflowA (B counters only), 3=disabled.
- */
-
-static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k,
-                         uint16_t Trig)
-{
-       DEBIreplace(dev, k->MyCRA, ~CRAMSK_LOADSRC_A,
-                   Trig << CRABIT_LOADSRC_A);
-}
-
-static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k,
-                         uint16_t Trig)
-{
-       DEBIreplace(dev, k->MyCRB, ~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL),
-                   Trig << CRBBIT_LOADSRC_B);
-}
-
-static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRA) >> CRABIT_LOADSRC_A) & 3;
-}
-
-static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRB) >> CRBBIT_LOADSRC_B) & 3;
-}
-
-/* Return/set counter interrupt source and clear any captured
- * index/overflow events.  IntSource: 0=Disabled, 1=OverflowOnly,
- * 2=IndexOnly, 3=IndexAndOverflow.
- */
-
-static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
-                       uint16_t IntSource)
-{
-       struct s626_private *devpriv = dev->private;
-
-       /*  Reset any pending counter overflow or index captures. */
-       DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL,
-                   CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
-
-       /*  Program counter interrupt source. */
-       DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A,
-                   IntSource << CRABIT_INTSRC_A);
-
-       /*  Update MISC2 interrupt enable mask. */
-       devpriv->CounterIntEnabs =
-           (devpriv->CounterIntEnabs & ~k->
-            MyEventBits[3]) | k->MyEventBits[IntSource];
-}
-
-static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
-                       uint16_t IntSource)
-{
-       struct s626_private *devpriv = dev->private;
-       uint16_t crb;
-
-       /*  Cache writeable CRB register image. */
-       crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;
-
-       /*  Reset any pending counter overflow or index captures. */
-       DEBIwrite(dev, k->MyCRB,
-                 (uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B));
-
-       /*  Program counter interrupt source. */
-       DEBIwrite(dev, k->MyCRB,
-                 (uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource <<
-                                                         CRBBIT_INTSRC_B)));
-
-       /*  Update MISC2 interrupt enable mask. */
-       devpriv->CounterIntEnabs =
-           (devpriv->CounterIntEnabs & ~k->
-            MyEventBits[3]) | k->MyEventBits[IntSource];
-}
-
-static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRA) >> CRABIT_INTSRC_A) & 3;
-}
-
-static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k)
-{
-       return (DEBIread(dev, k->MyCRB) >> CRBBIT_INTSRC_B) & 3;
-}
-
-/*  Return/set the clock multiplier. */
-
-/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
-/* { */
-/*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKMULT ) | ( value << STDBIT_CLKMULT ) ), FALSE ); */
-/* } */
-
-/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k )  */
-/* { */
-/*   return ( k->GetMode(dev, k ) >> STDBIT_CLKMULT ) & 3; */
-/* } */
-
-/* Return/set the clock polarity. */
-
-/* static void SetClkPol( struct comedi_device *dev,struct enc_private *k, uint16_t value )  */
-/* { */
-/*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKPOL ) | ( value << STDBIT_CLKPOL ) ), FALSE ); */
-/* } */
-
-/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k )  */
-/* { */
-/*   return ( k->GetMode(dev, k ) >> STDBIT_CLKPOL ) & 1; */
-/* } */
-
-/* Return/set the clock source.  */
-
-/* static void SetClkSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value )  */
-/* { */
-/*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKSRC ) | ( value << STDBIT_CLKSRC ) ), FALSE ); */
-/* } */
-
-/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k )  */
-/* { */
-/*   return ( k->GetMode(dev, k ) >> STDBIT_CLKSRC ) & 3; */
-/* } */
-
-/* Return/set the index polarity. */
-
-/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
-/* { */
-/*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXPOL ) | ( (value != 0) << STDBIT_INDXPOL ) ), FALSE ); */
-/* } */
-
-/* static uint16_t GetIndexPol(struct comedi_device *dev, struct enc_private *k )  */
-/* { */
-/*   return ( k->GetMode(dev, k ) >> STDBIT_INDXPOL ) & 1; */
-/* } */
-
-/*  Return/set the index source. */
-
-/* static void SetIndexSrc(struct comedi_device *dev, struct enc_private *k, uint16_t value )  */
-/* { */
-/*   k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXSRC ) | ( (value != 0) << STDBIT_INDXSRC ) ), FALSE ); */
-/* } */
-
-/* static uint16_t GetIndexSrc(struct comedi_device *dev, struct enc_private *k )  */
-/* { */
-/*   return ( k->GetMode(dev, k ) >> STDBIT_INDXSRC ) & 1; */
-/* } */
-
-/*  Generate an index pulse. */
-
-static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k)
-{
-       register uint16_t cra;
-
-       cra = DEBIread(dev, k->MyCRA);  /*  Pulse index. */
-       DEBIwrite(dev, k->MyCRA, (uint16_t) (cra ^ CRAMSK_INDXPOL_A));
-       DEBIwrite(dev, k->MyCRA, cra);
-}
-
-static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k)
-{
-       register uint16_t crb;
-
-       crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;        /*  Pulse index. */
-       DEBIwrite(dev, k->MyCRB, (uint16_t) (crb ^ CRBMSK_INDXPOL_B));
-       DEBIwrite(dev, k->MyCRB, crb);
-}
-
-static struct enc_private enc_private_data[] = {
-       {
-               .GetEnable      = GetEnable_A,
-               .GetIntSrc      = GetIntSrc_A,
-               .GetLoadTrig    = GetLoadTrig_A,
-               .GetMode        = GetMode_A,
-               .PulseIndex     = PulseIndex_A,
-               .SetEnable      = SetEnable_A,
-               .SetIntSrc      = SetIntSrc_A,
-               .SetLoadTrig    = SetLoadTrig_A,
-               .SetMode        = SetMode_A,
-               .ResetCapFlags  = ResetCapFlags_A,
-               .MyCRA          = LP_CR0A,
-               .MyCRB          = LP_CR0B,
-               .MyLatchLsw     = LP_CNTR0ALSW,
-               .MyEventBits    = EVBITS(0),
-       }, {
-               .GetEnable      = GetEnable_A,
-               .GetIntSrc      = GetIntSrc_A,
-               .GetLoadTrig    = GetLoadTrig_A,
-               .GetMode        = GetMode_A,
-               .PulseIndex     = PulseIndex_A,
-               .SetEnable      = SetEnable_A,
-               .SetIntSrc      = SetIntSrc_A,
-               .SetLoadTrig    = SetLoadTrig_A,
-               .SetMode        = SetMode_A,
-               .ResetCapFlags  = ResetCapFlags_A,
-               .MyCRA          = LP_CR1A,
-               .MyCRB          = LP_CR1B,
-               .MyLatchLsw     = LP_CNTR1ALSW,
-               .MyEventBits    = EVBITS(1),
-       }, {
-               .GetEnable      = GetEnable_A,
-               .GetIntSrc      = GetIntSrc_A,
-               .GetLoadTrig    = GetLoadTrig_A,
-               .GetMode        = GetMode_A,
-               .PulseIndex     = PulseIndex_A,
-               .SetEnable      = SetEnable_A,
-               .SetIntSrc      = SetIntSrc_A,
-               .SetLoadTrig    = SetLoadTrig_A,
-               .SetMode        = SetMode_A,
-               .ResetCapFlags  = ResetCapFlags_A,
-               .MyCRA          = LP_CR2A,
-               .MyCRB          = LP_CR2B,
-               .MyLatchLsw     = LP_CNTR2ALSW,
-               .MyEventBits    = EVBITS(2),
-       }, {
-               .GetEnable      = GetEnable_B,
-               .GetIntSrc      = GetIntSrc_B,
-               .GetLoadTrig    = GetLoadTrig_B,
-               .GetMode        = GetMode_B,
-               .PulseIndex     = PulseIndex_B,
-               .SetEnable      = SetEnable_B,
-               .SetIntSrc      = SetIntSrc_B,
-               .SetLoadTrig    = SetLoadTrig_B,
-               .SetMode        = SetMode_B,
-               .ResetCapFlags  = ResetCapFlags_B,
-               .MyCRA          = LP_CR0A,
-               .MyCRB          = LP_CR0B,
-               .MyLatchLsw     = LP_CNTR0BLSW,
-               .MyEventBits    = EVBITS(3),
-       }, {
-               .GetEnable      = GetEnable_B,
-               .GetIntSrc      = GetIntSrc_B,
-               .GetLoadTrig    = GetLoadTrig_B,
-               .GetMode        = GetMode_B,
-               .PulseIndex     = PulseIndex_B,
-               .SetEnable      = SetEnable_B,
-               .SetIntSrc      = SetIntSrc_B,
-               .SetLoadTrig    = SetLoadTrig_B,
-               .SetMode        = SetMode_B,
-               .ResetCapFlags  = ResetCapFlags_B,
-               .MyCRA          = LP_CR1A,
-               .MyCRB          = LP_CR1B,
-               .MyLatchLsw     = LP_CNTR1BLSW,
-               .MyEventBits    = EVBITS(4),
-       }, {
-               .GetEnable      = GetEnable_B,
-               .GetIntSrc      = GetIntSrc_B,
-               .GetLoadTrig    = GetLoadTrig_B,
-               .GetMode        = GetMode_B,
-               .PulseIndex     = PulseIndex_B,
-               .SetEnable      = SetEnable_B,
-               .SetIntSrc      = SetIntSrc_B,
-               .SetLoadTrig    = SetLoadTrig_B,
-               .SetMode        = SetMode_B,
-               .ResetCapFlags  = ResetCapFlags_B,
-               .MyCRA          = LP_CR2A,
-               .MyCRB          = LP_CR2B,
-               .MyLatchLsw     = LP_CNTR2BLSW,
-               .MyEventBits    = EVBITS(5),
-       },
-};
-
-static void CountersInit(struct comedi_device *dev)
+static void s626_counters_init(struct comedi_device *dev)
 {
        int chan;
-       struct enc_private *k;
-       uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /*  Preload upon */
-           /*  index. */
-           (INDXSRC_SOFT << BF_INDXSRC) |      /*  Disable hardware index. */
-           (CLKSRC_COUNTER << BF_CLKSRC) |     /*  Operating mode is counter. */
-           (CLKPOL_POS << BF_CLKPOL) | /*  Active high clock. */
-           (CNTDIR_UP << BF_CLKPOL) |  /*  Count direction is up. */
-           (CLKMULT_1X << BF_CLKMULT) |        /*  Clock multiplier is 1x. */
-           (CLKENAB_INDEX << BF_CLKENAB);      /*  Enabled by index */
-
-       /*  Disable all counter interrupts and clear any captured counter events. */
+       const struct s626_enc_info *k;
+       uint16_t setup =
+               /* Preload upon index. */
+               (S626_LOADSRC_INDX << S626_BF_LOADSRC) |
+               /* Disable hardware index. */
+               (S626_INDXSRC_SOFT << S626_BF_INDXSRC) |
+               /* Operating mode is counter. */
+               (S626_ENCMODE_COUNTER << S626_BF_ENCMODE) |
+               /* Active high clock. */
+               (S626_CLKPOL_POS << S626_BF_CLKPOL) |
+               /* Clock multiplier is 1x. */
+               (S626_CLKMULT_1X << S626_BF_CLKMULT) |
+               /* Enabled by index */
+               (S626_CLKENAB_INDEX << S626_BF_CLKENAB);
+
+       /*
+        * Disable all counter interrupts and clear any captured counter events.
+        */
        for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
-               k = &encpriv[chan];
-               k->SetMode(dev, k, Setup, TRUE);
-               k->SetIntSrc(dev, k, 0);
-               k->ResetCapFlags(dev, k);
-               k->SetEnable(dev, k, CLKENAB_ALWAYS);
+               k = &s626_enc_chan_info[chan];
+               k->set_mode(dev, k, setup, true);
+               k->set_int_src(dev, k, 0);
+               k->reset_cap_flags(dev, k);
+               k->set_enable(dev, k, S626_CLKENAB_ALWAYS);
        }
 }
 
@@ -2316,17 +2550,17 @@ static int s626_allocate_dma_buffers(struct comedi_device *dev)
        void *addr;
        dma_addr_t appdma;
 
-       addr = pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma);
+       addr = pci_alloc_consistent(pcidev, S626_DMABUF_SIZE, &appdma);
        if (!addr)
                return -ENOMEM;
-       devpriv->ANABuf.LogicalBase = addr;
-       devpriv->ANABuf.PhysicalBase = appdma;
+       devpriv->ana_buf.logical_base = addr;
+       devpriv->ana_buf.physical_base = appdma;
 
-       addr = pci_alloc_consistent(pcidev, DMABUF_SIZE, &appdma);
+       addr = pci_alloc_consistent(pcidev, S626_DMABUF_SIZE, &appdma);
        if (!addr)
                return -ENOMEM;
-       devpriv->RPSBuf.LogicalBase = addr;
-       devpriv->RPSBuf.PhysicalBase = appdma;
+       devpriv->rps_buf.logical_base = addr;
+       devpriv->rps_buf.physical_base = appdma;
 
        return 0;
 }
@@ -2334,42 +2568,43 @@ static int s626_allocate_dma_buffers(struct comedi_device *dev)
 static void s626_initialize(struct comedi_device *dev)
 {
        struct s626_private *devpriv = dev->private;
-       dma_addr_t pPhysBuf;
+       dma_addr_t phys_buf;
        uint16_t chan;
        int i;
 
        /* Enable DEBI and audio pins, enable I2C interface */
-       s626_mc_enable(dev, MC1_DEBI | MC1_AUDIO | MC1_I2C, P_MC1);
+       s626_mc_enable(dev, S626_MC1_DEBI | S626_MC1_AUDIO | S626_MC1_I2C,
+                      S626_P_MC1);
 
        /*
-        *  Configure DEBI operating mode
+        * Configure DEBI operating mode
         *
-        *   Local bus is 16 bits wide
-        *   Declare DEBI transfer timeout interval
-        *   Set up byte lane steering
-        *   Intel-compatible local bus (DEBI never times out)
+        *  Local bus is 16 bits wide
+        *  Declare DEBI transfer timeout interval
+        *  Set up byte lane steering
+        *  Intel-compatible local bus (DEBI never times out)
         */
-       writel(DEBI_CFG_SLAVE16 |
-              (DEBI_TOUT << DEBI_CFG_TOUT_BIT) |
-              DEBI_SWAP | DEBI_CFG_INTEL,
-              devpriv->mmio + P_DEBICFG);
+       writel(S626_DEBI_CFG_SLAVE16 |
+              (S626_DEBI_TOUT << S626_DEBI_CFG_TOUT_BIT) | S626_DEBI_SWAP |
+              S626_DEBI_CFG_INTEL, devpriv->mmio + S626_P_DEBICFG);
 
        /* Disable MMU paging */
-       writel(DEBI_PAGE_DISABLE, devpriv->mmio + P_DEBIPAGE);
+       writel(S626_DEBI_PAGE_DISABLE, devpriv->mmio + S626_P_DEBIPAGE);
 
        /* Init GPIO so that ADC Start* is negated */
-       writel(GPIO_BASE | GPIO1_HI, devpriv->mmio + P_GPIO);
+       writel(S626_GPIO_BASE | S626_GPIO1_HI, devpriv->mmio + S626_P_GPIO);
 
        /* I2C device address for onboard eeprom (revb) */
-       devpriv->I2CAdrs = 0xA0;
+       devpriv->i2c_adrs = 0xA0;
 
        /*
         * Issue an I2C ABORT command to halt any I2C
         * operation in progress and reset BUSY flag.
         */
-       writel(I2C_CLKSEL | I2C_ABORT, devpriv->mmio + P_I2CSTAT);
-       s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2);
-       while (!(readl(devpriv->mmio + P_MC2) & MC2_UPLD_IIC))
+       writel(S626_I2C_CLKSEL | S626_I2C_ABORT,
+              devpriv->mmio + S626_P_I2CSTAT);
+       s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
+       while (!(readl(devpriv->mmio + S626_P_MC2) & S626_MC2_UPLD_IIC))
                ;
 
        /*
@@ -2377,9 +2612,9 @@ static void s626_initialize(struct comedi_device *dev)
         * reg twice to reset all  I2C error flags.
         */
        for (i = 0; i < 2; i++) {
-               writel(I2C_CLKSEL, devpriv->mmio + P_I2CSTAT);
-               s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2);
-               while (!s626_mc_test(dev, MC2_UPLD_IIC, P_MC2))
+               writel(S626_I2C_CLKSEL, devpriv->mmio + S626_P_I2CSTAT);
+               s626_mc_enable(dev, S626_MC2_UPLD_IIC, S626_P_MC2);
+               while (!s626_mc_test(dev, S626_MC2_UPLD_IIC, S626_P_MC2))
                        ;
        }
 
@@ -2389,31 +2624,32 @@ static void s626_initialize(struct comedi_device *dev)
         * DAC data setup times are satisfied, enable DAC serial
         * clock out.
         */
-       writel(ACON2_INIT, devpriv->mmio + P_ACON2);
+       writel(S626_ACON2_INIT, devpriv->mmio + S626_P_ACON2);
 
        /*
         * Set up TSL1 slot list, which is used to control the
-        * accumulation of ADC data: RSD1 = shift data in on SD1.
-        * SIB_A1  = store data uint8_t at next available location
+        * accumulation of ADC data: S626_RSD1 = shift data in on SD1.
+        * S626_SIB_A1  = store data uint8_t at next available location
         * in FB BUFFER1 register.
         */
-       writel(RSD1 | SIB_A1, devpriv->mmio + P_TSL1);
-       writel(RSD1 | SIB_A1 | EOS, devpriv->mmio + P_TSL1 + 4);
+       writel(S626_RSD1 | S626_SIB_A1, devpriv->mmio + S626_P_TSL1);
+       writel(S626_RSD1 | S626_SIB_A1 | S626_EOS,
+              devpriv->mmio + S626_P_TSL1 + 4);
 
        /* Enable TSL1 slot list so that it executes all the time */
-       writel(ACON1_ADCSTART, devpriv->mmio + P_ACON1);
+       writel(S626_ACON1_ADCSTART, devpriv->mmio + S626_P_ACON1);
 
        /*
         * Initialize RPS registers used for ADC
         */
 
        /* Physical start of RPS program */
-       writel((uint32_t)devpriv->RPSBuf.PhysicalBase,
-              devpriv->mmio + P_RPSADDR1);
+       writel((uint32_t)devpriv->rps_buf.physical_base,
+              devpriv->mmio + S626_P_RPSADDR1);
        /* RPS program performs no explicit mem writes */
-       writel(0, devpriv->mmio + P_RPSPAGE1);
+       writel(0, devpriv->mmio + S626_P_RPSPAGE1);
        /* Disable RPS timeouts */
-       writel(0, devpriv->mmio + P_RPS1_TOUT);
+       writel(0, devpriv->mmio + S626_P_RPS1_TOUT);
 
 #if 0
        /*
@@ -2425,38 +2661,37 @@ static void s626_initialize(struct comedi_device *dev)
         * because the SAA7146 ADC interface does not start up in
         * a defined state after a PCI reset.
         */
-
        {
-       uint8_t PollList;
-       uint16_t AdcData;
-       uint16_t StartVal;
-       uint16_t index;
-       unsigned int data[16];
+               uint8_t poll_list;
+               uint16_t adc_data;
+               uint16_t start_val;
+               uint16_t index;
+               unsigned int data[16];
 
-       /* Create a simple polling list for analog input channel 0 */
-       PollList = EOPL;
-       ResetADC(dev, &PollList);
+               /* Create a simple polling list for analog input channel 0 */
+               poll_list = S626_EOPL;
+               s626_reset_adc(dev, &poll_list);
 
-       /* Get initial ADC value */
-       s626_ai_rinsn(dev, dev->subdevices, NULL, data);
-       StartVal = data[0];
-
-       /*
-        * VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED EXECUTION.
-        *
-        * Invoke ADCs until the new ADC value differs from the initial
-        * value or a timeout occurs.  The timeout protects against the
-        * possibility that the driver is restarting and the ADC data is a
-        * fixed value resulting from the applied ADC analog input being
-        * unusually quiet or at the rail.
-        */
-       for (index = 0; index < 500; index++) {
+               /* Get initial ADC value */
                s626_ai_rinsn(dev, dev->subdevices, NULL, data);
-               AdcData = data[0];
-               if (AdcData != StartVal)
-                       break;
-       }
+               start_val = data[0];
 
+               /*
+                * VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED
+                * EXECUTION.
+                *
+                * Invoke ADCs until the new ADC value differs from the initial
+                * value or a timeout occurs.  The timeout protects against the
+                * possibility that the driver is restarting and the ADC data is
+                * a fixed value resulting from the applied ADC analog input
+                * being unusually quiet or at the rail.
+                */
+               for (index = 0; index < 500; index++) {
+                       s626_ai_rinsn(dev, dev->subdevices, NULL, data);
+                       adc_data = data[0];
+                       if (adc_data != start_val)
+                               break;
+               }
        }
 #endif /* SAA7146 BUG WORKAROUND */
 
@@ -2469,7 +2704,7 @@ static void s626_initialize(struct comedi_device *dev)
         *   burst length = 1 DWORD
         *   threshold = 1 DWORD.
         */
-       writel(0, devpriv->mmio + P_PCI_BT_A);
+       writel(0, devpriv->mmio + S626_P_PCI_BT_A);
 
        /*
         * Init Audio2's output DMA physical addresses.  The protection
@@ -2477,18 +2712,18 @@ static void s626_initialize(struct comedi_device *dev)
         * single DWORD will be transferred each time a DMA transfer is
         * enabled.
         */
-       pPhysBuf = devpriv->ANABuf.PhysicalBase +
-                  (DAC_WDMABUF_OS * sizeof(uint32_t));
-       writel((uint32_t)pPhysBuf, devpriv->mmio + P_BASEA2_OUT);
-       writel((uint32_t)(pPhysBuf + sizeof(uint32_t)),
-              devpriv->mmio + P_PROTA2_OUT);
+       phys_buf = devpriv->ana_buf.physical_base +
+                  (S626_DAC_WDMABUF_OS * sizeof(uint32_t));
+       writel((uint32_t)phys_buf, devpriv->mmio + S626_P_BASEA2_OUT);
+       writel((uint32_t)(phys_buf + sizeof(uint32_t)),
+              devpriv->mmio + S626_P_PROTA2_OUT);
 
        /*
         * Cache Audio2's output DMA buffer logical address.  This is
         * where DAC data is buffered for A2 output DMA transfers.
         */
-       devpriv->pDacWBuf = (uint32_t *)devpriv->ANABuf.LogicalBase +
-                           DAC_WDMABUF_OS;
+       devpriv->dac_wbuf = (uint32_t *)devpriv->ana_buf.logical_base +
+                           S626_DAC_WDMABUF_OS;
 
        /*
         * Audio2's output channels does not use paging.  The
@@ -2496,7 +2731,7 @@ static void s626_initialize(struct comedi_device *dev)
         * DMAC will automatically halt and its PCI address pointer
         * will be reset when the protection address is reached.
         */
-       writel(8, devpriv->mmio + P_PAGEA2_OUT);
+       writel(8, devpriv->mmio + S626_P_PAGEA2_OUT);
 
        /*
         * Initialize time slot list 2 (TSL2), which is used to control
@@ -2511,7 +2746,8 @@ static void s626_initialize(struct comedi_device *dev)
         */
 
        /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2 */
-       writel(XSD2 | RSD3 | SIB_A2 | EOS, devpriv->mmio + VECTPORT(0));
+       writel(S626_XSD2 | S626_RSD3 | S626_SIB_A2 | S626_EOS,
+              devpriv->mmio + S626_VECTPORT(0));
 
        /*
         * Initialize slot 1, which is constant.  Slot 1 causes a
@@ -2523,18 +2759,18 @@ static void s626_initialize(struct comedi_device *dev)
         */
 
        /* Slot 1: Fetch DWORD from Audio2's output FIFO */
-       writel(LF_A2, devpriv->mmio + VECTPORT(1));
+       writel(S626_LF_A2, devpriv->mmio + S626_VECTPORT(1));
 
        /* Start DAC's audio interface (TSL2) running */
-       writel(ACON1_DACSTART, devpriv->mmio + P_ACON1);
+       writel(S626_ACON1_DACSTART, devpriv->mmio + S626_P_ACON1);
 
        /*
         * Init Trim DACs to calibrated values.  Do it twice because the
         * SAA7146 audio channel does not always reset properly and
         * sometimes causes the first few TrimDAC writes to malfunction.
         */
-       LoadTrimDACs(dev);
-       LoadTrimDACs(dev);
+       s626_load_trim_dacs(dev);
+       s626_load_trim_dacs(dev);
 
        /*
         * Manually init all gate array hardware in case this is a soft
@@ -2549,10 +2785,10 @@ static void s626_initialize(struct comedi_device *dev)
         * polarity images.
         */
        for (chan = 0; chan < S626_DAC_CHANNELS; chan++)
-               SetDAC(dev, chan, 0);
+               s626_set_dac(dev, chan, 0);
 
        /* Init counters */
-       CountersInit(dev);
+       s626_counters_init(dev);
 
        /*
         * Without modifying the state of the Battery Backup enab, disable
@@ -2560,8 +2796,8 @@ static void s626_initialize(struct comedi_device *dev)
         * standard DIO (vs. counter overflow) mode, disable the battery
         * charger, and reset the watchdog interval selector to zero.
         */
-       WriteMISC2(dev, (uint16_t)(DEBIread(dev, LP_RDMISC2) &
-                                  MISC2_BATT_ENABLE));
+       s626_write_misc2(dev, (s626_debi_read(dev, S626_LP_RDMISC2) &
+                              S626_MISC2_BATT_ENABLE));
 
        /* Initialize the digital I/O subsystem */
        s626_dio_init(dev);
@@ -2588,10 +2824,10 @@ static int s626_auto_attach(struct comedi_device *dev,
                return -ENOMEM;
 
        /* disable master interrupt */
-       writel(0, devpriv->mmio + P_IER);
+       writel(0, devpriv->mmio + S626_P_IER);
 
        /* soft reset */
-       writel(MC1_SOFT_RESET, devpriv->mmio + P_MC1);
+       writel(S626_MC1_SOFT_RESET, devpriv->mmio + S626_P_MC1);
 
        /* DMA FIXME DMA// */
 
@@ -2670,7 +2906,7 @@ static int s626_auto_attach(struct comedi_device *dev,
        s->io_bits      = 0xffff;
        s->private      = (void *)2;    /* DIO group 2 */
        s->range_table  = &range_digital;
-       s->insn_config  = s626_dio_insn_config;
+       s->insn_config  = s626_dio_insn_config;
        s->insn_bits    = s626_dio_insn_bits;
 
        s = &dev->subdevices[5];
@@ -2679,7 +2915,6 @@ static int s626_auto_attach(struct comedi_device *dev,
        s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL;
        s->n_chan       = S626_ENCODER_CHANNELS;
        s->maxdata      = 0xffffff;
-       s->private      = enc_private_data;
        s->range_table  = &range_unknown;
        s->insn_config  = s626_enc_insn_config;
        s->insn_read    = s626_enc_insn_read;
@@ -2703,20 +2938,22 @@ static void s626_detach(struct comedi_device *dev)
                if (devpriv->mmio) {
                        /* interrupt mask */
                        /* Disable master interrupt */
-                       writel(0, devpriv->mmio + P_IER);
+                       writel(0, devpriv->mmio + S626_P_IER);
                        /* Clear board's IRQ status flag */
-                       writel(IRQ_GPIO3 | IRQ_RPS1,
-                              devpriv->mmio + P_ISR);
+                       writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1,
+                              devpriv->mmio + S626_P_ISR);
 
-                       /*  Disable the watchdog timer and battery charger. */
-                       WriteMISC2(dev, 0);
+                       /* Disable the watchdog timer and battery charger. */
+                       s626_write_misc2(dev, 0);
 
                        /* Close all interfaces on 7146 device */
-                       writel(MC1_SHUTDOWN, devpriv->mmio + P_MC1);
-                       writel(ACON1_BASE, devpriv->mmio + P_ACON1);
+                       writel(S626_MC1_SHUTDOWN, devpriv->mmio + S626_P_MC1);
+                       writel(S626_ACON1_BASE, devpriv->mmio + S626_P_ACON1);
 
-                       CloseDMAB(dev, &devpriv->RPSBuf, DMABUF_SIZE);
-                       CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE);
+                       s626_close_dma_b(dev, &devpriv->rps_buf,
+                                        S626_DMABUF_SIZE);
+                       s626_close_dma_b(dev, &devpriv->ana_buf,
+                                        S626_DMABUF_SIZE);
                }
 
                if (dev->irq)
@@ -2746,8 +2983,8 @@ static int s626_pci_probe(struct pci_dev *dev,
  * Philips SAA7146 media/dvb based cards.
  */
 static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = {
-       { PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626,
-               PCI_SUBVENDOR_ID_S626, PCI_SUBDEVICE_ID_S626, 0, 0, 0 },
+       { PCI_DEVICE_SUB(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146,
+                        0x6000, 0x0272) },
        { 0 }
 };
 MODULE_DEVICE_TABLE(pci, s626_pci_table);
index a85e6bdcad0750905f32c1078b4310e9d364db50..f6b68bf1df3e03ee89cebb978bc8efe81ba461f7 100644 (file)
 /*
-  comedi/drivers/s626.h
-  Sensoray s626 Comedi driver, header file
-
-  COMEDI - Linux Control and Measurement Device Interface
-  Copyright (C) 2000 David A. Schleef <ds@schleef.org>
-
-  Based on Sensoray Model 626 Linux driver Version 0.2
-  Copyright (C) 2002-2004 Sensoray Co., Inc.
-
-  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.
-*/
-
-/*
-  Driver: s626.o (s626.ko)
-  Description: Sensoray 626 driver
-  Devices: Sensoray s626
-  Authors: Gianluca Palli <gpalli@deis.unibo.it>,
-  Updated: Thu, 12 Jul 2005
-  Status: experimental
-
-  Configuration Options:
-  analog input:
-   none
-
-  analog output:
-   none
-
-  digital channel:
-   s626 has 3 dio subdevices (2,3 and 4) each with 16 i/o channels
-   supported configuration options:
-   INSN_CONFIG_DIO_QUERY
-   COMEDI_INPUT
-   COMEDI_OUTPUT
-
-  encoder:
-   Every channel must be configured before reading.
-
-   Example code
-
-   insn.insn=INSN_CONFIG;   // configuration instruction
-   insn.n=1;                // number of operation (must be 1)
-   insn.data=&initialvalue; // initial value loaded into encoder
-                            // during configuration
-   insn.subdev=5;           // encoder subdevice
-   insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); // encoder_channel
-                                                        // to configure
-
-   comedi_do_insn(cf,&insn); // executing configuration
-*/
-
-#if !defined(TRUE)
-#define TRUE    (1)
-#endif
-
-#if !defined(FALSE)
-#define FALSE   (0)
-#endif
-
-#define S626_SIZE 0x0200
-#define DMABUF_SIZE                    4096    /*  4k pages */
+ * comedi/drivers/s626.h
+ * Sensoray s626 Comedi driver, header file
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ *
+ * Based on Sensoray Model 626 Linux driver Version 0.2
+ * Copyright (C) 2002-2004 Sensoray Co., Inc.
+ *
+ * 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.
+ */
+
+#ifndef S626_H_INCLUDED
+#define S626_H_INCLUDED
+
+#define S626_DMABUF_SIZE       4096    /* 4k pages */
 
 #define S626_ADC_CHANNELS       16
 #define S626_DAC_CHANNELS       4
 #define S626_ENCODER_CHANNELS   6
 #define S626_DIO_CHANNELS       48
-#define S626_DIO_BANKS         3       /*  Number of DIO groups. */
-#define S626_DIO_EXTCHANS      40      /*  Number of */
-                                       /*  extended-capability */
-                                       /*  DIO channels. */
-
-#define NUM_TRIMDACS   12      /*  Number of valid TrimDAC channels. */
-
-/*  PCI bus interface types. */
-#define INTEL                          1       /*  Intel bus type. */
-#define MOTOROLA                       2       /*  Motorola bus type. */
+#define S626_DIO_BANKS         3       /* Number of DIO groups. */
+#define S626_DIO_EXTCHANS      40      /* Number of extended-capability
+                                        * DIO channels. */
 
-#define PLATFORM               INTEL   /*  *** SELECT PLATFORM TYPE *** */
+#define S626_NUM_TRIMDACS      12      /* Number of valid TrimDAC channels. */
 
-#define RANGE_5V                0x10   /*  +/-5V range */
-#define RANGE_10V               0x00   /*  +/-10V range */
+/* PCI bus interface types. */
+#define S626_INTEL             1       /* Intel bus type. */
+#define S626_MOTOROLA          2       /* Motorola bus type. */
 
-#define EOPL                   0x80    /*  End of ADC poll list marker. */
-#define GSEL_BIPOLAR5V         0x00F0  /*  LP_GSEL setting for 5V bipolar range. */
-#define GSEL_BIPOLAR10V                0x00A0  /*  LP_GSEL setting for 10V bipolar range. */
+#define S626_PLATFORM          S626_INTEL /* *** SELECT PLATFORM TYPE *** */
 
-/*  Error codes that must be visible to this base class. */
-#define ERR_ILLEGAL_PARM       0x00010000      /*  Illegal function parameter value was specified. */
-#define ERR_I2C                        0x00020000      /*  I2C error. */
-#define ERR_COUNTERSETUP       0x00200000      /*  Illegal setup specified for counter channel. */
-#define ERR_DEBI_TIMEOUT       0x00400000      /*  DEBI transfer timed out. */
+#define S626_RANGE_5V          0x10    /* +/-5V range */
+#define S626_RANGE_10V         0x00    /* +/-10V range */
 
-/*  Organization (physical order) and size (in DWORDs) of logical DMA buffers contained by ANA_DMABUF. */
-#define ADC_DMABUF_DWORDS      40      /*  ADC DMA buffer must hold 16 samples, plus pre/post garbage samples. */
-#define DAC_WDMABUF_DWORDS     1       /*  DAC output DMA buffer holds a single sample. */
+#define S626_EOPL              0x80    /* End of ADC poll list marker. */
+#define S626_GSEL_BIPOLAR5V    0x00F0  /* S626_LP_GSEL setting 5V bipolar. */
+#define S626_GSEL_BIPOLAR10V   0x00A0  /* S626_LP_GSEL setting 10V bipolar. */
 
-/*  All remaining space in 4KB DMA buffer is available for the RPS1 program. */
+/* Error codes that must be visible to this base class. */
+#define S626_ERR_ILLEGAL_PARM  0x00010000      /* Illegal function parameter
+                                                * value was specified. */
+#define S626_ERR_I2C           0x00020000      /* I2C error. */
+#define S626_ERR_COUNTERSETUP  0x00200000      /* Illegal setup specified for
+                                                * counter channel. */
+#define S626_ERR_DEBI_TIMEOUT  0x00400000      /* DEBI transfer timed out. */
 
-/*  Address offsets, in DWORDS, from base of DMA buffer. */
-#define DAC_WDMABUF_OS         ADC_DMABUF_DWORDS
-
-/*  Interrupt enab bit in ISR and IER. */
-#define IRQ_GPIO3              0x00000040      /*  IRQ enable for GPIO3. */
-#define IRQ_RPS1                0x10000000
-#define ISR_AFOU               0x00000800
+/*
+ * Organization (physical order) and size (in DWORDs) of logical DMA buffers
+ * contained by ANA_DMABUF.
+ */
+#define S626_ADC_DMABUF_DWORDS 40      /* ADC DMA buffer must hold 16 samples,
+                                        * plus pre/post garbage samples. */
+#define S626_DAC_WDMABUF_DWORDS        1       /* DAC output DMA buffer holds a single
+                                        * sample. */
+
+/* All remaining space in 4KB DMA buffer is available for the RPS1 program. */
+
+/* Address offsets, in DWORDS, from base of DMA buffer. */
+#define S626_DAC_WDMABUF_OS    S626_ADC_DMABUF_DWORDS
+
+/*  Interrupt enable bit in ISR and IER. */
+#define S626_IRQ_GPIO3         0x00000040      /* IRQ enable for GPIO3. */
+#define S626_IRQ_RPS1          0x10000000
+#define S626_ISR_AFOU          0x00000800
 /* Audio fifo under/overflow  detected. */
 
-#define IRQ_COINT1A             0x0400 /* conter 1A overflow interrupt mask */
-#define IRQ_COINT1B             0x0800 /* conter 1B overflow interrupt mask */
-#define IRQ_COINT2A             0x1000 /* conter 2A overflow interrupt mask */
-#define IRQ_COINT2B             0x2000 /* conter 2B overflow interrupt mask */
-#define IRQ_COINT3A             0x4000 /* conter 3A overflow interrupt mask */
-#define IRQ_COINT3B             0x8000 /* conter 3B overflow interrupt mask */
-
-/*  RPS command codes. */
-#define RPS_CLRSIGNAL          0x00000000      /*  CLEAR SIGNAL */
-#define RPS_SETSIGNAL          0x10000000      /*  SET SIGNAL */
-#define RPS_NOP                        0x00000000      /*  NOP */
-#define RPS_PAUSE              0x20000000      /*  PAUSE */
-#define RPS_UPLOAD             0x40000000      /*  UPLOAD */
-#define RPS_JUMP               0x80000000      /*  JUMP */
-#define RPS_LDREG              0x90000100      /*  LDREG (1 uint32_t only) */
-#define RPS_STREG              0xA0000100      /*  STREG (1 uint32_t only) */
-#define RPS_STOP               0x50000000      /*  STOP */
-#define RPS_IRQ                 0x60000000     /*  IRQ */
-
-#define RPS_LOGICAL_OR         0x08000000      /*  Logical OR conditionals. */
-#define RPS_INVERT             0x04000000      /*  Test for negated semaphores. */
-#define RPS_DEBI               0x00000002      /*  DEBI done */
-
-#define RPS_SIG0               0x00200000      /*  RPS semaphore 0 (used by ADC). */
-#define RPS_SIG1               0x00400000      /*  RPS semaphore 1 (used by DAC). */
-#define RPS_SIG2               0x00800000      /*  RPS semaphore 2 (not used). */
-#define RPS_GPIO2              0x00080000      /*  RPS GPIO2 */
-#define RPS_GPIO3              0x00100000      /*  RPS GPIO3 */
-
-#define RPS_SIGADC             RPS_SIG0        /*  Trigger/status for ADC's RPS program. */
-#define RPS_SIGDAC             RPS_SIG1        /*  Trigger/status for DAC's RPS program. */
-
-/*  RPS clock parameters. */
-#define RPSCLK_SCALAR          8       /*  This is apparent ratio of PCI/RPS clks (undocumented!!). */
-#define RPSCLK_PER_US          (33 / RPSCLK_SCALAR)    /*  Number of RPS clocks in one microsecond. */
-
-/*  Event counter source addresses. */
-#define SBA_RPS_A0             0x27    /*  Time of RPS0 busy, in PCI clocks. */
-
-/*  GPIO constants. */
-#define GPIO_BASE              0x10004000      /*  GPIO 0,2,3 = inputs, GPIO3 = IRQ; GPIO1 = out. */
-#define GPIO1_LO               0x00000000      /*  GPIO1 set to LOW. */
-#define GPIO1_HI               0x00001000      /*  GPIO1 set to HIGH. */
-
-/*  Primary Status Register (PSR) constants. */
-#define PSR_DEBI_E             0x00040000      /*  DEBI event flag. */
-#define PSR_DEBI_S             0x00080000      /*  DEBI status flag. */
-#define PSR_A2_IN              0x00008000      /*  Audio output DMA2 protection address reached. */
-#define PSR_AFOU               0x00000800      /*  Audio FIFO under/overflow detected. */
-#define PSR_GPIO2              0x00000020      /*  GPIO2 input pin: 0=AdcBusy, 1=AdcIdle. */
-#define PSR_EC0S               0x00000001      /*  Event counter 0 threshold reached. */
-
-/*  Secondary Status Register (SSR) constants. */
-#define SSR_AF2_OUT            0x00000200      /*  Audio 2 output FIFO under/overflow detected. */
-
-/*  Master Control Register 1 (MC1) constants. */
-#define MC1_SOFT_RESET         0x80000000      /*  Invoke 7146 soft reset. */
-#define MC1_SHUTDOWN           0x3FFF0000      /*  Shut down all MC1-controlled enables. */
-
-#define MC1_ERPS1              0x2000  /*  enab/disable RPS task 1. */
-#define MC1_ERPS0              0x1000  /*  enab/disable RPS task 0. */
-#define MC1_DEBI               0x0800  /*  enab/disable DEBI pins. */
-#define MC1_AUDIO              0x0200  /*  enab/disable audio port pins. */
-#define MC1_I2C                        0x0100  /*  enab/disable I2C interface. */
-#define MC1_A2OUT              0x0008  /*  enab/disable transfer on A2 out. */
-#define MC1_A2IN               0x0004  /*  enab/disable transfer on A2 in. */
-#define MC1_A1IN               0x0001  /*  enab/disable transfer on A1 in. */
-
-/*  Master Control Register 2 (MC2) constants. */
-#define MC2_UPLD_DEBIq         0x00020002      /*  Upload DEBI registers. */
-#define MC2_UPLD_IICq          0x00010001      /*  Upload I2C registers. */
-#define MC2_RPSSIG2_ONq                0x20002000      /*  Assert RPS_SIG2. */
-#define MC2_RPSSIG1_ONq                0x10001000      /*  Assert RPS_SIG1. */
-#define MC2_RPSSIG0_ONq                0x08000800      /*  Assert RPS_SIG0. */
-#define MC2_UPLD_DEBI_MASKq    0x00000002      /*  Upload DEBI mask. */
-#define MC2_UPLD_IIC_MASKq     0x00000001      /*  Upload I2C mask. */
-#define MC2_RPSSIG2_MASKq      0x00002000      /*  RPS_SIG2 bit mask. */
-#define MC2_RPSSIG1_MASKq      0x00001000      /*  RPS_SIG1 bit mask. */
-#define MC2_RPSSIG0_MASKq      0x00000800      /*  RPS_SIG0 bit mask. */
-
-#define MC2_DELAYTRIG_4USq     MC2_RPSSIG1_ON
-#define MC2_DELAYBUSY_4USq     MC2_RPSSIG1_MASK
-
-#define        MC2_DELAYTRIG_6USq      MC2_RPSSIG2_ON
-#define MC2_DELAYBUSY_6USq     MC2_RPSSIG2_MASK
-
-#define MC2_UPLD_DEBI          0x0002  /*  Upload DEBI. */
-#define MC2_UPLD_IIC           0x0001  /*  Upload I2C. */
-#define MC2_RPSSIG2            0x2000  /*  RPS signal 2 (not used). */
-#define MC2_RPSSIG1            0x1000  /*  RPS signal 1 (DAC RPS busy). */
-#define MC2_RPSSIG0            0x0800  /*  RPS signal 0 (ADC RPS busy). */
-
-#define MC2_ADC_RPS            MC2_RPSSIG0     /*  ADC RPS busy. */
-#define MC2_DAC_RPS            MC2_RPSSIG1     /*  DAC RPS busy. */
-
-/* ***** oldies ***** */
-#define MC2_UPLD_DEBIQ         0x00020002      /*  Upload DEBI registers. */
-#define MC2_UPLD_IICQ          0x00010001      /*  Upload I2C registers. */
-
-/*  PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS */
-#define P_PCI_BT_A             0x004C  /* Audio DMA burst/threshold control. */
-#define P_DEBICFG               0x007C /* DEBI configuration. */
-#define P_DEBICMD               0x0080 /* DEBI command. */
-#define P_DEBIPAGE              0x0084 /* DEBI page. */
-#define P_DEBIAD                0x0088 /* DEBI target address. */
-#define P_I2CCTRL               0x008C /* I2C control. */
-#define P_I2CSTAT               0x0090 /* I2C status. */
-#define P_BASEA2_IN            0x00AC  /* Audio input 2 base physical DMAbuf
+#define S626_IRQ_COINT1A       0x0400  /* counter 1A overflow interrupt mask */
+#define S626_IRQ_COINT1B       0x0800  /* counter 1B overflow interrupt mask */
+#define S626_IRQ_COINT2A       0x1000  /* counter 2A overflow interrupt mask */
+#define S626_IRQ_COINT2B       0x2000  /* counter 2B overflow interrupt mask */
+#define S626_IRQ_COINT3A       0x4000  /* counter 3A overflow interrupt mask */
+#define S626_IRQ_COINT3B       0x8000  /* counter 3B overflow interrupt mask */
+
+/* RPS command codes. */
+#define S626_RPS_CLRSIGNAL     0x00000000      /* CLEAR SIGNAL */
+#define S626_RPS_SETSIGNAL     0x10000000      /* SET SIGNAL */
+#define S626_RPS_NOP           0x00000000      /* NOP */
+#define S626_RPS_PAUSE         0x20000000      /* PAUSE */
+#define S626_RPS_UPLOAD                0x40000000      /* UPLOAD */
+#define S626_RPS_JUMP          0x80000000      /* JUMP */
+#define S626_RPS_LDREG         0x90000100      /* LDREG (1 uint32_t only) */
+#define S626_RPS_STREG         0xA0000100      /* STREG (1 uint32_t only) */
+#define S626_RPS_STOP          0x50000000      /* STOP */
+#define S626_RPS_IRQ           0x60000000      /* IRQ */
+
+#define S626_RPS_LOGICAL_OR    0x08000000      /* Logical OR conditionals. */
+#define S626_RPS_INVERT                0x04000000      /* Test for negated
+                                                * semaphores. */
+#define S626_RPS_DEBI          0x00000002      /* DEBI done */
+
+#define S626_RPS_SIG0          0x00200000      /* RPS semaphore 0
+                                                * (used by ADC). */
+#define S626_RPS_SIG1          0x00400000      /* RPS semaphore 1
+                                                * (used by DAC). */
+#define S626_RPS_SIG2          0x00800000      /* RPS semaphore 2
+                                                * (not used). */
+#define S626_RPS_GPIO2         0x00080000      /* RPS GPIO2 */
+#define S626_RPS_GPIO3         0x00100000      /* RPS GPIO3 */
+
+#define S626_RPS_SIGADC                S626_RPS_SIG0   /* Trigger/status for
+                                                * ADC's RPS program. */
+#define S626_RPS_SIGDAC                S626_RPS_SIG1   /* Trigger/status for
+                                                * DAC's RPS program. */
+
+/* RPS clock parameters. */
+#define S626_RPSCLK_SCALAR     8       /* This is apparent ratio of
+                                        * PCI/RPS clks (undocumented!!). */
+#define S626_RPSCLK_PER_US     (33 / S626_RPSCLK_SCALAR)
+                                       /* Number of RPS clocks in one
+                                        * microsecond. */
+
+/* Event counter source addresses. */
+#define S626_SBA_RPS_A0                0x27    /* Time of RPS0 busy, in PCI clocks. */
+
+/* GPIO constants. */
+#define S626_GPIO_BASE         0x10004000      /* GPIO 0,2,3 = inputs,
+                                                * GPIO3 = IRQ; GPIO1 = out. */
+#define S626_GPIO1_LO          0x00000000      /* GPIO1 set to LOW. */
+#define S626_GPIO1_HI          0x00001000      /* GPIO1 set to HIGH. */
+
+/* Primary Status Register (PSR) constants. */
+#define S626_PSR_DEBI_E                0x00040000      /* DEBI event flag. */
+#define S626_PSR_DEBI_S                0x00080000      /* DEBI status flag. */
+#define S626_PSR_A2_IN         0x00008000      /* Audio output DMA2 protection
+                                                * address reached. */
+#define S626_PSR_AFOU          0x00000800      /* Audio FIFO under/overflow
+                                                * detected. */
+#define S626_PSR_GPIO2         0x00000020      /* GPIO2 input pin: 0=AdcBusy,
+                                                * 1=AdcIdle. */
+#define S626_PSR_EC0S          0x00000001      /* Event counter 0 threshold
+                                                * reached. */
+
+/* Secondary Status Register (SSR) constants. */
+#define S626_SSR_AF2_OUT       0x00000200      /* Audio 2 output FIFO
+                                                * under/overflow detected. */
+
+/* Master Control Register 1 (MC1) constants. */
+#define S626_MC1_SOFT_RESET    0x80000000      /* Invoke 7146 soft reset. */
+#define S626_MC1_SHUTDOWN      0x3FFF0000      /* Shut down all MC1-controlled
+                                                * enables. */
+
+#define S626_MC1_ERPS1         0x2000  /* Enab/disable RPS task 1. */
+#define S626_MC1_ERPS0         0x1000  /* Enab/disable RPS task 0. */
+#define S626_MC1_DEBI          0x0800  /* Enab/disable DEBI pins. */
+#define S626_MC1_AUDIO         0x0200  /* Enab/disable audio port pins. */
+#define S626_MC1_I2C           0x0100  /* Enab/disable I2C interface. */
+#define S626_MC1_A2OUT         0x0008  /* Enab/disable transfer on A2 out. */
+#define S626_MC1_A2IN          0x0004  /* Enab/disable transfer on A2 in. */
+#define S626_MC1_A1IN          0x0001  /* Enab/disable transfer on A1 in. */
+
+/* Master Control Register 2 (MC2) constants. */
+#define S626_MC2_UPLD_DEBI     0x0002  /* Upload DEBI. */
+#define S626_MC2_UPLD_IIC      0x0001  /* Upload I2C. */
+#define S626_MC2_RPSSIG2       0x2000  /* RPS signal 2 (not used). */
+#define S626_MC2_RPSSIG1       0x1000  /* RPS signal 1 (DAC RPS busy). */
+#define S626_MC2_RPSSIG0       0x0800  /* RPS signal 0 (ADC RPS busy). */
+
+#define S626_MC2_ADC_RPS       S626_MC2_RPSSIG0        /* ADC RPS busy. */
+#define S626_MC2_DAC_RPS       S626_MC2_RPSSIG1        /* DAC RPS busy. */
+
+/* PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS */
+#define S626_P_PCI_BT_A                0x004C  /* Audio DMA burst/threshold control. */
+#define S626_P_DEBICFG         0x007C  /* DEBI configuration. */
+#define S626_P_DEBICMD         0x0080  /* DEBI command. */
+#define S626_P_DEBIPAGE                0x0084  /* DEBI page. */
+#define S626_P_DEBIAD          0x0088  /* DEBI target address. */
+#define S626_P_I2CCTRL         0x008C  /* I2C control. */
+#define S626_P_I2CSTAT         0x0090  /* I2C status. */
+#define S626_P_BASEA2_IN       0x00AC  /* Audio input 2 base physical DMAbuf
                                         * address. */
-#define P_PROTA2_IN            0x00B0  /* Audio input 2 physical DMAbuf
+#define S626_P_PROTA2_IN       0x00B0  /* Audio input 2 physical DMAbuf
                                         * protection address. */
-#define P_PAGEA2_IN            0x00B4  /* Audio input 2 paging attributes. */
-#define P_BASEA2_OUT           0x00B8  /* Audio output 2 base physical DMAbuf
+#define S626_P_PAGEA2_IN       0x00B4  /* Audio input 2 paging attributes. */
+#define S626_P_BASEA2_OUT      0x00B8  /* Audio output 2 base physical DMAbuf
                                         * address. */
-#define P_PROTA2_OUT           0x00BC  /* Audio output 2 physical DMAbuf
+#define S626_P_PROTA2_OUT      0x00BC  /* Audio output 2 physical DMAbuf
                                         * protection address. */
-#define P_PAGEA2_OUT           0x00C0  /* Audio output 2 paging attributes. */
-#define P_RPSPAGE0              0x00C4 /* RPS0 page. */
-#define P_RPSPAGE1              0x00C8 /* RPS1 page. */
-#define P_RPS0_TOUT            0x00D4  /* RPS0 time-out. */
-#define P_RPS1_TOUT            0x00D8  /* RPS1 time-out. */
-#define P_IER                   0x00DC /* Interrupt enable. */
-#define P_GPIO                  0x00E0 /* General-purpose I/O. */
-#define P_EC1SSR               0x00E4  /* Event counter set 1 source select. */
-#define P_ECT1R                        0x00EC  /* Event counter threshold set 1. */
-#define P_ACON1                 0x00F4 /* Audio control 1. */
-#define P_ACON2                 0x00F8 /* Audio control 2. */
-#define P_MC1                   0x00FC /* Master control 1. */
-#define P_MC2                   0x0100 /* Master control 2. */
-#define P_RPSADDR0              0x0104 /* RPS0 instruction pointer. */
-#define P_RPSADDR1              0x0108 /* RPS1 instruction pointer. */
-#define P_ISR                   0x010C /* Interrupt status. */
-#define P_PSR                   0x0110 /* Primary status. */
-#define P_SSR                   0x0114 /* Secondary status. */
-#define P_EC1R                 0x0118  /* Event counter set 1. */
-#define P_ADP4                 0x0138  /* Logical audio DMA pointer of audio
+#define S626_P_PAGEA2_OUT      0x00C0  /* Audio output 2 paging attributes. */
+#define S626_P_RPSPAGE0                0x00C4  /* RPS0 page. */
+#define S626_P_RPSPAGE1                0x00C8  /* RPS1 page. */
+#define S626_P_RPS0_TOUT       0x00D4  /* RPS0 time-out. */
+#define S626_P_RPS1_TOUT       0x00D8  /* RPS1 time-out. */
+#define S626_P_IER             0x00DC  /* Interrupt enable. */
+#define S626_P_GPIO            0x00E0  /* General-purpose I/O. */
+#define S626_P_EC1SSR          0x00E4  /* Event counter set 1 source select. */
+#define S626_P_ECT1R           0x00EC  /* Event counter threshold set 1. */
+#define S626_P_ACON1           0x00F4  /* Audio control 1. */
+#define S626_P_ACON2           0x00F8  /* Audio control 2. */
+#define S626_P_MC1             0x00FC  /* Master control 1. */
+#define S626_P_MC2             0x0100  /* Master control 2. */
+#define S626_P_RPSADDR0                0x0104  /* RPS0 instruction pointer. */
+#define S626_P_RPSADDR1                0x0108  /* RPS1 instruction pointer. */
+#define S626_P_ISR             0x010C  /* Interrupt status. */
+#define S626_P_PSR             0x0110  /* Primary status. */
+#define S626_P_SSR             0x0114  /* Secondary status. */
+#define S626_P_EC1R            0x0118  /* Event counter set 1. */
+#define S626_P_ADP4            0x0138  /* Logical audio DMA pointer of audio
                                         * input FIFO A2_IN. */
-#define P_FB_BUFFER1            0x0144 /* Audio feedback buffer 1. */
-#define P_FB_BUFFER2            0x0148 /* Audio feedback buffer 2. */
-#define P_TSL1                  0x0180 /* Audio time slot list 1. */
-#define P_TSL2                  0x01C0 /* Audio time slot list 2. */
+#define S626_P_FB_BUFFER1      0x0144  /* Audio feedback buffer 1. */
+#define S626_P_FB_BUFFER2      0x0148  /* Audio feedback buffer 2. */
+#define S626_P_TSL1            0x0180  /* Audio time slot list 1. */
+#define S626_P_TSL2            0x01C0  /* Audio time slot list 2. */
 
-/*  LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS */
-/*  Analog I/O registers: */
-#define LP_DACPOL              0x0082  /*   Write DAC polarity. */
-#define LP_GSEL                        0x0084  /*   Write ADC gain. */
-#define LP_ISEL                        0x0086  /*   Write ADC channel select. */
+/* LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS */
+/* Analog I/O registers: */
+#define S626_LP_DACPOL         0x0082  /* Write DAC polarity. */
+#define S626_LP_GSEL           0x0084  /* Write ADC gain. */
+#define S626_LP_ISEL           0x0086  /* Write ADC channel select. */
 
 /* Digital I/O registers */
-#define LP_RDDIN(x)            (0x0040 + (x) * 0x10)   /* R: digital input */
-#define LP_WRINTSEL(x)         (0x0042 + (x) * 0x10)   /* W: int enable */
-#define LP_WREDGSEL(x)         (0x0044 + (x) * 0x10)   /* W: edge selection */
-#define LP_WRCAPSEL(x)         (0x0046 + (x) * 0x10)   /* W: capture enable */
-#define LP_RDCAPFLG(x)         (0x0048 + (x) * 0x10)   /* R: edges captured */
-#define LP_WRDOUT(x)           (0x0048 + (x) * 0x10)   /* W: digital output */
-#define LP_RDINTSEL(x)         (0x004a + (x) * 0x10)   /* R: int enable */
-#define LP_RDEDGSEL(x)         (0x004c + (x) * 0x10)   /* R: edge selection */
-#define LP_RDCAPSEL(x)         (0x004e + (x) * 0x10)   /* R: capture enable */
-
-/*  Counter Registers (read/write): */
-#define LP_CR0A                        0x0000  /*   0A setup register. */
-#define LP_CR0B                        0x0002  /*   0B setup register. */
-#define LP_CR1A                        0x0004  /*   1A setup register. */
-#define LP_CR1B                        0x0006  /*   1B setup register. */
-#define LP_CR2A                        0x0008  /*   2A setup register. */
-#define LP_CR2B                        0x000A  /*   2B setup register. */
-
-/*  Counter PreLoad (write) and Latch (read) Registers: */
-#define        LP_CNTR0ALSW            0x000C  /*   0A lsw. */
-#define        LP_CNTR0AMSW            0x000E  /*   0A msw. */
-#define        LP_CNTR0BLSW            0x0010  /*   0B lsw. */
-#define        LP_CNTR0BMSW            0x0012  /*   0B msw. */
-#define        LP_CNTR1ALSW            0x0014  /*   1A lsw. */
-#define        LP_CNTR1AMSW            0x0016  /*   1A msw. */
-#define        LP_CNTR1BLSW            0x0018  /*   1B lsw. */
-#define        LP_CNTR1BMSW            0x001A  /*   1B msw. */
-#define        LP_CNTR2ALSW            0x001C  /*   2A lsw. */
-#define        LP_CNTR2AMSW            0x001E  /*   2A msw. */
-#define        LP_CNTR2BLSW            0x0020  /*   2B lsw. */
-#define        LP_CNTR2BMSW            0x0022  /*   2B msw. */
-
-/*  Miscellaneous Registers (read/write): */
-#define LP_MISC1               0x0088  /*   Read/write Misc1. */
-#define LP_WRMISC2             0x0090  /*   Write Misc2. */
-#define LP_RDMISC2             0x0082  /*   Read Misc2. */
-
-/*  Bit masks for MISC1 register that are the same for reads and writes. */
-#define MISC1_WENABLE          0x8000  /* enab writes to MISC2 (except Clear
+#define S626_LP_RDDIN(x)       (0x0040 + (x) * 0x10)   /* R: digital input */
+#define S626_LP_WRINTSEL(x)    (0x0042 + (x) * 0x10)   /* W: int enable */
+#define S626_LP_WREDGSEL(x)    (0x0044 + (x) * 0x10)   /* W: edge selection */
+#define S626_LP_WRCAPSEL(x)    (0x0046 + (x) * 0x10)   /* W: capture enable */
+#define S626_LP_RDCAPFLG(x)    (0x0048 + (x) * 0x10)   /* R: edges captured */
+#define S626_LP_WRDOUT(x)      (0x0048 + (x) * 0x10)   /* W: digital output */
+#define S626_LP_RDINTSEL(x)    (0x004a + (x) * 0x10)   /* R: int enable */
+#define S626_LP_RDEDGSEL(x)    (0x004c + (x) * 0x10)   /* R: edge selection */
+#define S626_LP_RDCAPSEL(x)    (0x004e + (x) * 0x10)   /* R: capture enable */
+
+/* Counter Registers (read/write): */
+#define S626_LP_CR0A           0x0000  /* 0A setup register. */
+#define S626_LP_CR0B           0x0002  /* 0B setup register. */
+#define S626_LP_CR1A           0x0004  /* 1A setup register. */
+#define S626_LP_CR1B           0x0006  /* 1B setup register. */
+#define S626_LP_CR2A           0x0008  /* 2A setup register. */
+#define S626_LP_CR2B           0x000A  /* 2B setup register. */
+
+/* Counter PreLoad (write) and Latch (read) Registers: */
+#define        S626_LP_CNTR0ALSW       0x000C  /* 0A lsw. */
+#define        S626_LP_CNTR0AMSW       0x000E  /* 0A msw. */
+#define        S626_LP_CNTR0BLSW       0x0010  /* 0B lsw. */
+#define        S626_LP_CNTR0BMSW       0x0012  /* 0B msw. */
+#define        S626_LP_CNTR1ALSW       0x0014  /* 1A lsw. */
+#define        S626_LP_CNTR1AMSW       0x0016  /* 1A msw. */
+#define        S626_LP_CNTR1BLSW       0x0018  /* 1B lsw. */
+#define        S626_LP_CNTR1BMSW       0x001A  /* 1B msw. */
+#define        S626_LP_CNTR2ALSW       0x001C  /* 2A lsw. */
+#define        S626_LP_CNTR2AMSW       0x001E  /* 2A msw. */
+#define        S626_LP_CNTR2BLSW       0x0020  /* 2B lsw. */
+#define        S626_LP_CNTR2BMSW       0x0022  /* 2B msw. */
+
+/* Miscellaneous Registers (read/write): */
+#define S626_LP_MISC1          0x0088  /* Read/write Misc1. */
+#define S626_LP_WRMISC2                0x0090  /* Write Misc2. */
+#define S626_LP_RDMISC2                0x0082  /* Read Misc2. */
+
+/* Bit masks for MISC1 register that are the same for reads and writes. */
+#define S626_MISC1_WENABLE     0x8000  /* enab writes to MISC2 (except Clear
                                         * Watchdog bit). */
-#define MISC1_WDISABLE         0x0000  /* Disable writes to MISC2. */
-#define MISC1_EDCAP            0x1000  /* enab edge capture on DIO chans
-                                        * specified by  LP_WRCAPSELx. */
-#define MISC1_NOEDCAP          0x0000  /* Disable edge capture on specified
+#define S626_MISC1_WDISABLE    0x0000  /* Disable writes to MISC2. */
+#define S626_MISC1_EDCAP       0x1000  /* Enable edge capture on DIO chans
+                                        * specified by S626_LP_WRCAPSELx. */
+#define S626_MISC1_NOEDCAP     0x0000  /* Disable edge capture on specified
                                         * DIO chans. */
 
-/*  Bit masks for MISC1 register reads. */
-#define RDMISC1_WDTIMEOUT      0x4000  /*  Watchdog timer timed out. */
-
-/*  Bit masks for MISC2 register writes. */
-#define WRMISC2_WDCLEAR                0x8000  /*  Reset watchdog timer to zero. */
-#define WRMISC2_CHARGE_ENABLE  0x4000  /*  enab battery trickle charging. */
-
-/*  Bit masks for MISC2 register that are the same for reads and writes. */
-#define MISC2_BATT_ENABLE      0x0008  /*  Backup battery enable. */
-#define MISC2_WDENABLE         0x0004  /*  Watchdog timer enable. */
-#define MISC2_WDPERIOD_MASK    0x0003  /*  Watchdog interval */
-                                               /*  select mask. */
-
-/*  Bit masks for ACON1 register. */
-#define A2_RUN                 0x40000000      /*  Run A2 based on TSL2. */
-#define A1_RUN                 0x20000000      /*  Run A1 based on TSL1. */
-#define A1_SWAP                        0x00200000      /*  Use big-endian for A1. */
-#define A2_SWAP                        0x00100000      /*  Use big-endian for A2. */
-#define WS_MODES               0x00019999      /*  WS0 = TSL1 trigger */
-                                               /*  input, WS1-WS4 = */
-                                               /*  CS* outputs. */
-
-#if PLATFORM == INTEL          /* Base ACON1 config: always run A1 based
-                                * on TSL1. */
-#define ACON1_BASE             (WS_MODES | A1_RUN)
-#elif PLATFORM == MOTOROLA
-#define ACON1_BASE             (WS_MODES | A1_RUN | A1_SWAP | A2_SWAP)
+/* Bit masks for MISC1 register reads. */
+#define S626_RDMISC1_WDTIMEOUT 0x4000  /* Watchdog timer timed out. */
+
+/* Bit masks for MISC2 register writes. */
+#define S626_WRMISC2_WDCLEAR   0x8000  /* Reset watchdog timer to zero. */
+#define S626_WRMISC2_CHARGE_ENABLE 0x4000 /* Enable battery trickle charging. */
+
+/* Bit masks for MISC2 register that are the same for reads and writes. */
+#define S626_MISC2_BATT_ENABLE 0x0008  /* Backup battery enable. */
+#define S626_MISC2_WDENABLE    0x0004  /* Watchdog timer enable. */
+#define S626_MISC2_WDPERIOD_MASK 0x0003        /* Watchdog interval select mask. */
+
+/* Bit masks for ACON1 register. */
+#define S626_A2_RUN            0x40000000      /* Run A2 based on TSL2. */
+#define S626_A1_RUN            0x20000000      /* Run A1 based on TSL1. */
+#define S626_A1_SWAP           0x00200000      /* Use big-endian for A1. */
+#define S626_A2_SWAP           0x00100000      /* Use big-endian for A2. */
+#define S626_WS_MODES          0x00019999      /* WS0 = TSL1 trigger input,
+                                                * WS1-WS4 = CS* outputs. */
+
+#if S626_PLATFORM == S626_INTEL                /* Base ACON1 config: always run
+                                        * A1 based on TSL1. */
+#define S626_ACON1_BASE                (S626_WS_MODES | S626_A1_RUN)
+#elif S626_PLATFORM == S626_MOTOROLA
+#define S626_ACON1_BASE                \
+       (S626_WS_MODES | S626_A1_RUN | S626_A1_SWAP | S626_A2_SWAP)
 #endif
 
-#define ACON1_ADCSTART         ACON1_BASE      /* Start ADC: run A1
-                                                *  based on TSL1. */
-#define ACON1_DACSTART         (ACON1_BASE | A2_RUN)
+#define S626_ACON1_ADCSTART    S626_ACON1_BASE /* Start ADC: run A1
+                                                * based on TSL1. */
+#define S626_ACON1_DACSTART    (S626_ACON1_BASE | S626_A2_RUN)
 /* Start transmit to DAC: run A2 based on TSL2. */
-#define ACON1_DACSTOP          ACON1_BASE      /*  Halt A2. */
-
-/*  Bit masks for ACON2 register. */
-#define A1_CLKSRC_BCLK1                0x00000000      /*  A1 bit rate = BCLK1 (ADC). */
-#define A2_CLKSRC_X1           0x00800000      /*  A2 bit rate = ACLK/1 (DACs). */
-#define A2_CLKSRC_X2           0x00C00000      /*  A2 bit rate = ACLK/2 (DACs). */
-#define A2_CLKSRC_X4           0x01400000      /*  A2 bit rate = ACLK/4 (DACs). */
-#define INVERT_BCLK2           0x00100000      /*  Invert BCLK2 (DACs). */
-#define BCLK2_OE               0x00040000      /*  enab BCLK2 (DACs). */
-#define ACON2_XORMASK          0x000C0000      /*  XOR mask for ACON2 */
-                                               /*  active-low bits. */
-
-#define ACON2_INIT             (ACON2_XORMASK ^ (A1_CLKSRC_BCLK1 | A2_CLKSRC_X2 | INVERT_BCLK2 | BCLK2_OE))
-
-/*  Bit masks for timeslot records. */
-#define WS1                    0x40000000      /*  WS output to assert. */
-#define WS2                    0x20000000
-#define WS3                    0x10000000
-#define WS4                    0x08000000
-#define RSD1                   0x01000000      /* Shift A1 data in on SD1. */
-#define SDW_A1                 0x00800000      /* Store rcv'd char at next
-                                                * char slot of DWORD1 buffer. */
-#define SIB_A1                 0x00400000      /* Store rcv'd char at next
+#define S626_ACON1_DACSTOP     S626_ACON1_BASE /* Halt A2. */
+
+/* Bit masks for ACON2 register. */
+#define S626_A1_CLKSRC_BCLK1   0x00000000      /* A1 bit rate = BCLK1 (ADC). */
+#define S626_A2_CLKSRC_X1      0x00800000      /* A2 bit rate = ACLK/1
+                                                * (DACs). */
+#define S626_A2_CLKSRC_X2      0x00C00000      /* A2 bit rate = ACLK/2
+                                                * (DACs). */
+#define S626_A2_CLKSRC_X4      0x01400000      /* A2 bit rate = ACLK/4
+                                                * (DACs). */
+#define S626_INVERT_BCLK2      0x00100000      /* Invert BCLK2 (DACs). */
+#define S626_BCLK2_OE          0x00040000      /* Enable BCLK2 (DACs). */
+#define S626_ACON2_XORMASK     0x000C0000      /* XOR mask for ACON2
+                                                * active-low bits. */
+
+#define S626_ACON2_INIT                (S626_ACON2_XORMASK ^ \
+                                (S626_A1_CLKSRC_BCLK1 | S626_A2_CLKSRC_X2 | \
+                                 S626_INVERT_BCLK2 | S626_BCLK2_OE))
+
+/* Bit masks for timeslot records. */
+#define S626_WS1               0x40000000      /* WS output to assert. */
+#define S626_WS2               0x20000000
+#define S626_WS3               0x10000000
+#define S626_WS4               0x08000000
+#define S626_RSD1              0x01000000      /* Shift A1 data in on SD1. */
+#define S626_SDW_A1            0x00800000      /* Store rcv'd char at next char
+                                                * slot of DWORD1 buffer. */
+#define S626_SIB_A1            0x00400000      /* Store rcv'd char at next
                                                 * char slot of FB1 buffer. */
-#define SF_A1                  0x00200000      /* Write unsigned long
+#define S626_SF_A1             0x00200000      /* Write unsigned long
                                                 * buffer to input FIFO. */
 
 /* Select parallel-to-serial converter's data source: */
-#define XFIFO_0                        0x00000000      /*    Data fifo byte 0. */
-#define XFIFO_1                        0x00000010      /*    Data fifo byte 1. */
-#define XFIFO_2                        0x00000020      /*    Data fifo byte 2. */
-#define XFIFO_3                        0x00000030      /*    Data fifo byte 3. */
-#define XFB0                   0x00000040      /*    FB_BUFFER byte 0. */
-#define XFB1                   0x00000050      /*    FB_BUFFER byte 1. */
-#define XFB2                   0x00000060      /*    FB_BUFFER byte 2. */
-#define XFB3                   0x00000070      /*    FB_BUFFER byte 3. */
-#define SIB_A2                 0x00000200      /* Store next dword from A2's
-                                                * input shifter to FB2 buffer. */
-#define SF_A2                  0x00000100      /* Store next dword from A2's
+#define S626_XFIFO_0           0x00000000      /* Data fifo byte 0. */
+#define S626_XFIFO_1           0x00000010      /* Data fifo byte 1. */
+#define S626_XFIFO_2           0x00000020      /* Data fifo byte 2. */
+#define S626_XFIFO_3           0x00000030      /* Data fifo byte 3. */
+#define S626_XFB0              0x00000040      /* FB_BUFFER byte 0. */
+#define S626_XFB1              0x00000050      /* FB_BUFFER byte 1. */
+#define S626_XFB2              0x00000060      /* FB_BUFFER byte 2. */
+#define S626_XFB3              0x00000070      /* FB_BUFFER byte 3. */
+#define S626_SIB_A2            0x00000200      /* Store next dword from A2's
+                                                * input shifter to FB2
+                                                * buffer. */
+#define S626_SF_A2             0x00000100      /* Store next dword from A2's
                                                 * input shifter to its input
                                                 * fifo. */
-#define LF_A2                  0x00000080      /* Load next dword from A2's
+#define S626_LF_A2             0x00000080      /* Load next dword from A2's
                                                 * output fifo into its
                                                 * output dword buffer. */
-#define XSD2                   0x00000008      /*  Shift data out on SD2. */
-#define RSD3                   0x00001800      /*  Shift data in on SD3. */
-#define RSD2                   0x00001000      /*  Shift data in on SD2. */
-#define LOW_A2                 0x00000002      /*  Drive last SD low */
-                                               /*  for 7 clks, then */
-                                               /*  tri-state. */
-#define EOS                    0x00000001      /*  End of superframe. */
-
-/*  I2C configuration constants. */
-#define I2C_CLKSEL             0x0400
-/* I2C bit rate = PCIclk/480 = 68.75 KHz. */
-
-#define I2C_BITRATE            68.75
-/* I2C bus data bit rate (determined by I2C_CLKSEL) in KHz. */
-
-#define I2C_WRTIME             15.0
-/* Worst case time, in msec, for EEPROM internal write op. */
-
-/*  I2C manifest constants. */
-
-/*  Max retries to wait for EEPROM write. */
-#define I2C_RETRIES            (I2C_WRTIME * I2C_BITRATE / 9.0)
-#define I2C_ERR                        0x0002  /*  I2C control/status */
-                                               /*  flag ERROR. */
-#define I2C_BUSY               0x0001  /*  I2C control/status */
-                                               /*  flag BUSY. */
-#define I2C_ABORT              0x0080  /*  I2C status flag ABORT. */
-#define I2C_ATTRSTART          0x3     /*  I2C attribute START. */
-#define I2C_ATTRCONT           0x2     /*  I2C attribute CONT. */
-#define I2C_ATTRSTOP           0x1     /*  I2C attribute STOP. */
-#define I2C_ATTRNOP            0x0     /*  I2C attribute NOP. */
-
-/*  I2C read command  | EEPROM address. */
-#define I2CR                   (devpriv->I2CAdrs | 1)
-
-/*  I2C write command | EEPROM address. */
-#define I2CW                   (devpriv->I2CAdrs)
-
-/*  Code macros used for constructing I2C command bytes. */
-#define I2C_B2(ATTR, VAL)      (((ATTR) << 6) | ((VAL) << 24))
-#define I2C_B1(ATTR, VAL)      (((ATTR) << 4) | ((VAL) << 16))
-#define I2C_B0(ATTR, VAL)      (((ATTR) << 2) | ((VAL) <<  8))
-
-/* oldest */
-#define P_DEBICFGq              0x007C /*  DEBI configuration. */
-#define P_DEBICMDq              0x0080 /*  DEBI command. */
-#define P_DEBIPAGEq             0x0084 /*  DEBI page. */
-#define P_DEBIADq               0x0088 /*  DEBI target address. */
-
-#define DEBI_CFG_TOQ           0x03C00000      /*  timeout (15 PCI cycles) */
-#define DEBI_CFG_FASTQ         0x10000000      /*  fast mode enable */
-#define DEBI_CFG_16Q           0x00080000      /*  16-bit access enable */
-#define DEBI_CFG_INCQ          0x00040000      /*  enable address increment */
-#define DEBI_CFG_TIMEROFFQ     0x00010000      /*  disable timer */
-#define DEBI_CMD_RDQ           0x00050000      /*  read immediate 2 bytes */
-#define DEBI_CMD_WRQ           0x00040000      /*  write immediate 2 bytes */
-#define DEBI_PAGE_DISABLEQ     0x00000000      /*  paging disable */
-
-/*  DEBI command constants. */
-#define DEBI_CMD_SIZE16                (2 << 17)       /*  Transfer size is */
-                                               /*  always 2 bytes. */
-#define DEBI_CMD_READ          0x00010000      /*  Read operation. */
-#define DEBI_CMD_WRITE         0x00000000      /*  Write operation. */
-
-/*  Read immediate 2 bytes. */
-#define DEBI_CMD_RDWORD                (DEBI_CMD_READ  | DEBI_CMD_SIZE16)
-
-/*  Write immediate 2 bytes. */
-#define DEBI_CMD_WRWORD                (DEBI_CMD_WRITE | DEBI_CMD_SIZE16)
-
-/*  DEBI configuration constants. */
-#define DEBI_CFG_XIRQ_EN       0x80000000      /*  enab external */
-                                               /*  interrupt on GPIO3. */
-#define DEBI_CFG_XRESUME       0x40000000      /*  Resume block */
-                                               /*  transfer when XIRQ */
-                                               /*  deasserted. */
-#define DEBI_CFG_FAST          0x10000000      /*  Fast mode enable. */
-
-/*  4-bit field that specifies DEBI timeout value in PCI clock cycles: */
-#define DEBI_CFG_TOUT_BIT      22      /*    Finish DEBI cycle after */
-                                       /*    this many clocks. */
-
-/*  2-bit field that specifies Endian byte lane steering: */
-#define DEBI_CFG_SWAP_NONE     0x00000000      /*    Straight - don't */
-                                               /*    swap any bytes */
-                                               /*    (Intel). */
-#define DEBI_CFG_SWAP_2                0x00100000      /*    2-byte swap (Motorola). */
-#define DEBI_CFG_SWAP_4                0x00200000      /*    4-byte swap. */
-#define DEBI_CFG_16            0x00080000      /*  Slave is able to */
-                                               /*  serve 16-bit */
-                                               /*  cycles. */
-
-#define DEBI_CFG_SLAVE16       0x00080000      /*  Slave is able to */
-                                               /*  serve 16-bit */
-                                               /*  cycles. */
-#define DEBI_CFG_INC           0x00040000      /*  enab address */
-                                               /*  increment for block */
-                                               /*  transfers. */
-#define DEBI_CFG_INTEL         0x00020000      /*  Intel style local bus. */
-#define DEBI_CFG_TIMEROFF      0x00010000      /*  Disable timer. */
-
-#if PLATFORM == INTEL
-
-#define DEBI_TOUT              7       /*  Wait 7 PCI clocks */
-                                               /*  (212 ns) before */
-                                               /*  polling RDY. */
-
-/*  Intel byte lane steering (pass through all byte lanes). */
-#define DEBI_SWAP              DEBI_CFG_SWAP_NONE
-
-#elif PLATFORM == MOTOROLA
-
-#define DEBI_TOUT              15      /*  Wait 15 PCI clocks (454 ns) */
-                                       /*  maximum before timing out. */
-#define DEBI_SWAP              DEBI_CFG_SWAP_2 /*  Motorola byte lane steering. */
+#define S626_XSD2              0x00000008      /* Shift data out on SD2. */
+#define S626_RSD3              0x00001800      /* Shift data in on SD3. */
+#define S626_RSD2              0x00001000      /* Shift data in on SD2. */
+#define S626_LOW_A2            0x00000002      /* Drive last SD low for 7 clks,
+                                                * then tri-state. */
+#define S626_EOS               0x00000001      /* End of superframe. */
+
+/* I2C configuration constants. */
+#define S626_I2C_CLKSEL                0x0400          /* I2C bit rate =
+                                                * PCIclk/480 = 68.75 KHz. */
+#define S626_I2C_BITRATE       68.75           /* I2C bus data bit rate
+                                                * (determined by
+                                                * S626_I2C_CLKSEL) in KHz. */
+#define S626_I2C_WRTIME                15.0            /* Worst case time, in msec,
+                                                * for EEPROM internal write
+                                                * op. */
+
+/* I2C manifest constants. */
+
+/* Max retries to wait for EEPROM write. */
+#define S626_I2C_RETRIES       (S626_I2C_WRTIME * S626_I2C_BITRATE / 9.0)
+#define S626_I2C_ERR           0x0002  /* I2C control/status flag ERROR. */
+#define S626_I2C_BUSY          0x0001  /* I2C control/status flag BUSY. */
+#define S626_I2C_ABORT         0x0080  /* I2C status flag ABORT. */
+#define S626_I2C_ATTRSTART     0x3     /* I2C attribute START. */
+#define S626_I2C_ATTRCONT      0x2     /* I2C attribute CONT. */
+#define S626_I2C_ATTRSTOP      0x1     /* I2C attribute STOP. */
+#define S626_I2C_ATTRNOP       0x0     /* I2C attribute NOP. */
+
+/* Code macros used for constructing I2C command bytes. */
+#define S626_I2C_B2(ATTR, VAL) (((ATTR) << 6) | ((VAL) << 24))
+#define S626_I2C_B1(ATTR, VAL) (((ATTR) << 4) | ((VAL) << 16))
+#define S626_I2C_B0(ATTR, VAL) (((ATTR) << 2) | ((VAL) <<  8))
+
+/* DEBI command constants. */
+#define S626_DEBI_CMD_SIZE16   (2 << 17)       /* Transfer size is always
+                                                * 2 bytes. */
+#define S626_DEBI_CMD_READ     0x00010000      /* Read operation. */
+#define S626_DEBI_CMD_WRITE    0x00000000      /* Write operation. */
+
+/* Read immediate 2 bytes. */
+#define S626_DEBI_CMD_RDWORD   (S626_DEBI_CMD_READ | S626_DEBI_CMD_SIZE16)
+
+/* Write immediate 2 bytes. */
+#define S626_DEBI_CMD_WRWORD   (S626_DEBI_CMD_WRITE | S626_DEBI_CMD_SIZE16)
+
+/* DEBI configuration constants. */
+#define S626_DEBI_CFG_XIRQ_EN  0x80000000      /* Enable external interrupt
+                                                * on GPIO3. */
+#define S626_DEBI_CFG_XRESUME  0x40000000      /* Resume block */
+                                               /* Transfer when XIRQ
+                                                * deasserted. */
+#define S626_DEBI_CFG_TOQ      0x03C00000      /* Timeout (15 PCI cycles). */
+#define S626_DEBI_CFG_FAST     0x10000000      /* Fast mode enable. */
+
+/* 4-bit field that specifies DEBI timeout value in PCI clock cycles: */
+#define S626_DEBI_CFG_TOUT_BIT 22      /* Finish DEBI cycle after this many
+                                        * clocks. */
+
+/* 2-bit field that specifies Endian byte lane steering: */
+#define S626_DEBI_CFG_SWAP_NONE        0x00000000      /* Straight - don't swap any
+                                                * bytes (Intel). */
+#define S626_DEBI_CFG_SWAP_2   0x00100000      /* 2-byte swap (Motorola). */
+#define S626_DEBI_CFG_SWAP_4   0x00200000      /* 4-byte swap. */
+#define S626_DEBI_CFG_SLAVE16  0x00080000      /* Slave is able to serve
+                                                * 16-bit cycles. */
+#define S626_DEBI_CFG_INC      0x00040000      /* Enable address increment
+                                                * for block transfers. */
+#define S626_DEBI_CFG_INTEL    0x00020000      /* Intel style local bus. */
+#define S626_DEBI_CFG_TIMEROFF 0x00010000      /* Disable timer. */
+
+#if S626_PLATFORM == S626_INTEL
+
+#define S626_DEBI_TOUT         7       /* Wait 7 PCI clocks (212 ns) before
+                                        * polling RDY. */
+
+/* Intel byte lane steering (pass through all byte lanes). */
+#define S626_DEBI_SWAP         S626_DEBI_CFG_SWAP_NONE
+
+#elif S626_PLATFORM == S626_MOTOROLA
+
+#define S626_DEBI_TOUT         15      /* Wait 15 PCI clocks (454 ns) maximum
+                                        * before timing out. */
+
+/* Motorola byte lane steering. */
+#define S626_DEBI_SWAP         S626_DEBI_CFG_SWAP_2
 
 #endif
 
-/*  DEBI page table constants. */
-#define DEBI_PAGE_DISABLE      0x00000000      /*  Paging disable. */
-
-/* ******* EXTRA FROM OTHER SANSORAY  * .h  ******* */
-
-/*  LoadSrc values: */
-#define LOADSRC_INDX           0       /*  Preload core in response to */
-                                       /*  Index. */
-#define LOADSRC_OVER           1       /*  Preload core in response to */
-                                       /*  Overflow. */
-#define LOADSRCB_OVERA         2       /*  Preload B core in response */
-                                       /*  to A Overflow. */
-#define LOADSRC_NONE           3       /*  Never preload core. */
-
-/*  IntSrc values: */
-#define INTSRC_NONE            0       /*  Interrupts disabled. */
-#define INTSRC_OVER            1       /*  Interrupt on Overflow. */
-#define INTSRC_INDX            2       /*  Interrupt on Index. */
-#define INTSRC_BOTH            3       /*  Interrupt on Index or Overflow. */
-
-/*  LatchSrc values: */
-#define LATCHSRC_AB_READ       0       /*  Latch on read. */
-#define LATCHSRC_A_INDXA       1       /*  Latch A on A Index. */
-#define LATCHSRC_B_INDXB       2       /*  Latch B on B Index. */
-#define LATCHSRC_B_OVERA       3       /*  Latch B on A Overflow. */
-
-/*  IndxSrc values: */
-#define INDXSRC_HARD           0       /*  Hardware or software index. */
-#define INDXSRC_SOFT           1       /*  Software index only. */
-
-/*  IndxPol values: */
-#define INDXPOL_POS            0       /*  Index input is active high. */
-#define INDXPOL_NEG            1       /*  Index input is active low. */
-
-/*  ClkSrc values: */
-#define CLKSRC_COUNTER         0       /*  Counter mode. */
-#define CLKSRC_TIMER           2       /*  Timer mode. */
-#define CLKSRC_EXTENDER                3       /*  Extender mode. */
-
-/*  ClkPol values: */
-#define CLKPOL_POS             0       /*  Counter/Extender clock is */
-                                       /*  active high. */
-#define CLKPOL_NEG             1       /*  Counter/Extender clock is */
-                                       /*  active low. */
-#define CNTDIR_UP              0       /*  Timer counts up. */
-#define CNTDIR_DOWN            1       /*  Timer counts down. */
-
-/*  ClkEnab values: */
-#define CLKENAB_ALWAYS         0       /*  Clock always enabled. */
-#define CLKENAB_INDEX          1       /*  Clock is enabled by index. */
-
-/*  ClkMult values: */
-#define CLKMULT_4X             0       /*  4x clock multiplier. */
-#define CLKMULT_2X             1       /*  2x clock multiplier. */
-#define CLKMULT_1X             2       /*  1x clock multiplier. */
-
-/*  Bit Field positions in COUNTER_SETUP structure: */
-#define BF_LOADSRC             9       /*  Preload trigger. */
-#define BF_INDXSRC             7       /*  Index source. */
-#define BF_INDXPOL             6       /*  Index polarity. */
-#define BF_CLKSRC              4       /*  Clock source. */
-#define BF_CLKPOL              3       /*  Clock polarity/count direction. */
-#define BF_CLKMULT             1       /*  Clock multiplier. */
-#define BF_CLKENAB             0       /*  Clock enable. */
-
-/*  Enumerated counter operating modes specified by ClkSrc bit field in */
-/*  a COUNTER_SETUP. */
-
-#define CLKSRC_COUNTER         0       /*  Counter: ENC_C clock, ENC_D */
-                                       /*  direction. */
-#define CLKSRC_TIMER           2       /*  Timer: SYS_C clock, */
-                                       /*  direction specified by */
-                                       /*  ClkPol. */
-#define CLKSRC_EXTENDER                3       /*  Extender: OVR_A clock, */
-                                       /*  ENC_D direction. */
-
-/*  Enumerated counter clock multipliers. */
-
-#define MULT_X0                        0x0003  /*  Supports no multipliers; */
-                                       /*  fixed physical multiplier = */
-                                       /*  3. */
-#define MULT_X1                        0x0002  /*  Supports multiplier x1; */
-                                       /*  fixed physical multiplier = */
-                                       /*  2. */
-#define MULT_X2                        0x0001  /*  Supports multipliers x1, */
-                                       /*  x2; physical multipliers = */
-                                       /*  1 or 2. */
-#define MULT_X4                        0x0000  /*  Supports multipliers x1, */
-                                       /*  x2, x4; physical */
-                                       /*  multipliers = 0, 1 or 2. */
-
-/*  Sanity-check limits for parameters. */
-
-#define NUM_COUNTERS           6       /*  Maximum valid counter */
-                                       /*  logical channel number. */
-#define NUM_INTSOURCES         4
-#define NUM_LATCHSOURCES       4
-#define NUM_CLKMULTS           4
-#define NUM_CLKSOURCES         4
-#define NUM_CLKPOLS            2
-#define NUM_INDEXPOLS          2
-#define NUM_INDEXSOURCES       2
-#define NUM_LOADTRIGS          4
-
-/*  Bit field positions in CRA and CRB counter control registers. */
-
-/*  Bit field positions in CRA: */
-#define CRABIT_INDXSRC_B       14      /*    B index source. */
-#define CRABIT_CLKSRC_B                12      /*    B clock source. */
-#define CRABIT_INDXPOL_A       11      /*    A index polarity. */
-#define CRABIT_LOADSRC_A        9      /*    A preload trigger. */
-#define CRABIT_CLKMULT_A        7      /*    A clock multiplier. */
-#define CRABIT_INTSRC_A                 5      /*    A interrupt source. */
-#define CRABIT_CLKPOL_A                 4      /*    A clock polarity. */
-#define CRABIT_INDXSRC_A        2      /*    A index source. */
-#define CRABIT_CLKSRC_A                 0      /*    A clock source. */
-
-/*  Bit field positions in CRB: */
-#define CRBBIT_INTRESETCMD     15      /*    Interrupt reset command. */
-#define CRBBIT_INTRESET_B      14      /*    B interrupt reset enable. */
-#define CRBBIT_INTRESET_A      13      /*    A interrupt reset enable. */
-#define CRBBIT_CLKENAB_A       12      /*    A clock enable. */
-#define CRBBIT_INTSRC_B                10      /*    B interrupt source. */
-#define CRBBIT_LATCHSRC                 8      /*    A/B latch source. */
-#define CRBBIT_LOADSRC_B        6      /*    B preload trigger. */
-#define CRBBIT_CLKMULT_B        3      /*    B clock multiplier. */
-#define CRBBIT_CLKENAB_B        2      /*    B clock enable. */
-#define CRBBIT_INDXPOL_B        1      /*    B index polarity. */
-#define CRBBIT_CLKPOL_B                 0      /*    B clock polarity. */
-
-/*  Bit field masks for CRA and CRB. */
-
-#define CRAMSK_INDXSRC_B       (3 << CRABIT_INDXSRC_B)
-#define CRAMSK_CLKSRC_B                (3 << CRABIT_CLKSRC_B)
-#define CRAMSK_INDXPOL_A       (1 << CRABIT_INDXPOL_A)
-#define CRAMSK_LOADSRC_A       (3 << CRABIT_LOADSRC_A)
-#define CRAMSK_CLKMULT_A       (3 << CRABIT_CLKMULT_A)
-#define CRAMSK_INTSRC_A                (3 << CRABIT_INTSRC_A)
-#define CRAMSK_CLKPOL_A                (3 << CRABIT_CLKPOL_A)
-#define CRAMSK_INDXSRC_A       (3 << CRABIT_INDXSRC_A)
-#define CRAMSK_CLKSRC_A                (3 << CRABIT_CLKSRC_A)
-
-#define CRBMSK_INTRESETCMD     (1 << CRBBIT_INTRESETCMD)
-#define CRBMSK_INTRESET_B      (1 << CRBBIT_INTRESET_B)
-#define CRBMSK_INTRESET_A      (1 << CRBBIT_INTRESET_A)
-#define CRBMSK_CLKENAB_A       (1 << CRBBIT_CLKENAB_A)
-#define CRBMSK_INTSRC_B                (3 << CRBBIT_INTSRC_B)
-#define CRBMSK_LATCHSRC                (3 << CRBBIT_LATCHSRC)
-#define CRBMSK_LOADSRC_B       (3 << CRBBIT_LOADSRC_B)
-#define CRBMSK_CLKMULT_B       (3 << CRBBIT_CLKMULT_B)
-#define CRBMSK_CLKENAB_B       (1 << CRBBIT_CLKENAB_B)
-#define CRBMSK_INDXPOL_B       (1 << CRBBIT_INDXPOL_B)
-#define CRBMSK_CLKPOL_B                (1 << CRBBIT_CLKPOL_B)
-
-#define CRBMSK_INTCTRL         (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A | CRBMSK_INTRESET_B)    /*  Interrupt reset control bits. */
-
-/*  Bit field positions for standardized SETUP structure. */
-
-#define STDBIT_INTSRC          13
-#define STDBIT_LATCHSRC                11
-#define STDBIT_LOADSRC          9
-#define STDBIT_INDXSRC          7
-#define STDBIT_INDXPOL          6
-#define STDBIT_CLKSRC           4
-#define STDBIT_CLKPOL           3
-#define STDBIT_CLKMULT          1
-#define STDBIT_CLKENAB          0
-
-/*  Bit field masks for standardized SETUP structure. */
-
-#define STDMSK_INTSRC          (3 << STDBIT_INTSRC)
-#define STDMSK_LATCHSRC                (3 << STDBIT_LATCHSRC)
-#define STDMSK_LOADSRC         (3 << STDBIT_LOADSRC)
-#define STDMSK_INDXSRC         (1 << STDBIT_INDXSRC)
-#define STDMSK_INDXPOL         (1 << STDBIT_INDXPOL)
-#define STDMSK_CLKSRC          (3 << STDBIT_CLKSRC)
-#define STDMSK_CLKPOL          (1 << STDBIT_CLKPOL)
-#define STDMSK_CLKMULT         (3 << STDBIT_CLKMULT)
-#define STDMSK_CLKENAB         (1 << STDBIT_CLKENAB)
-
-struct bufferDMA {
-       dma_addr_t PhysicalBase;
-       void *LogicalBase;
-       uint32_t DMAHandle;
-};
+/* DEBI page table constants. */
+#define S626_DEBI_PAGE_DISABLE 0x00000000      /* Paging disable. */
+
+/* ******* EXTRA FROM OTHER SENSORAY  * .h  ******* */
+
+/* LoadSrc values: */
+#define S626_LOADSRC_INDX      0       /* Preload core in response to Index. */
+#define S626_LOADSRC_OVER      1       /* Preload core in response to
+                                        * Overflow. */
+#define S626_LOADSRCB_OVERA    2       /* Preload B core in response to
+                                        * A Overflow. */
+#define S626_LOADSRC_NONE      3       /* Never preload core. */
+
+/* IntSrc values: */
+#define S626_INTSRC_NONE       0       /* Interrupts disabled. */
+#define S626_INTSRC_OVER       1       /* Interrupt on Overflow. */
+#define S626_INTSRC_INDX       2       /* Interrupt on Index. */
+#define S626_INTSRC_BOTH       3       /* Interrupt on Index or Overflow. */
+
+/* LatchSrc values: */
+#define S626_LATCHSRC_AB_READ  0       /* Latch on read. */
+#define S626_LATCHSRC_A_INDXA  1       /* Latch A on A Index. */
+#define S626_LATCHSRC_B_INDXB  2       /* Latch B on B Index. */
+#define S626_LATCHSRC_B_OVERA  3       /* Latch B on A Overflow. */
+
+/* IndxSrc values: */
+#define S626_INDXSRC_HARD      0       /* Hardware or software index. */
+#define S626_INDXSRC_SOFT      1       /* Software index only. */
+
+/* IndxPol values: */
+#define S626_INDXPOL_POS       0       /* Index input is active high. */
+#define S626_INDXPOL_NEG       1       /* Index input is active low. */
+
+/* Logical encoder mode values: */
+#define S626_ENCMODE_COUNTER   0       /* Counter mode. */
+#define S626_ENCMODE_TIMER     2       /* Timer mode. */
+#define S626_ENCMODE_EXTENDER  3       /* Extender mode. */
+
+/* Physical CntSrc values (for Counter A source and Counter B source): */
+#define S626_CNTSRC_ENCODER    0       /* Encoder */
+#define S626_CNTSRC_DIGIN      1       /* Digital inputs */
+#define S626_CNTSRC_SYSCLK     2       /* System clock up */
+#define S626_CNTSRC_SYSCLK_DOWN        3       /* System clock down */
+
+/* ClkPol values: */
+#define S626_CLKPOL_POS                0       /* Counter/Extender clock is
+                                        * active high. */
+#define S626_CLKPOL_NEG                1       /* Counter/Extender clock is
+                                        * active low. */
+#define S626_CNTDIR_UP         0       /* Timer counts up. */
+#define S626_CNTDIR_DOWN       1       /* Timer counts down. */
+
+/* ClkEnab values: */
+#define S626_CLKENAB_ALWAYS    0       /* Clock always enabled. */
+#define S626_CLKENAB_INDEX     1       /* Clock is enabled by index. */
+
+/* ClkMult values: */
+#define S626_CLKMULT_4X                0       /* 4x clock multiplier. */
+#define S626_CLKMULT_2X                1       /* 2x clock multiplier. */
+#define S626_CLKMULT_1X                2       /* 1x clock multiplier. */
+
+/* Bit Field positions in COUNTER_SETUP structure: */
+#define S626_BF_LOADSRC                9       /* Preload trigger. */
+#define S626_BF_INDXSRC                7       /* Index source. */
+#define S626_BF_INDXPOL                6       /* Index polarity. */
+#define S626_BF_ENCMODE                4       /* Encoder mode. */
+#define S626_BF_CLKPOL         3       /* Clock polarity/count direction. */
+#define S626_BF_CLKMULT                1       /* Clock multiplier. */
+#define S626_BF_CLKENAB                0       /* Clock enable. */
+
+/* Enumerated counter clock multipliers. */
+
+#define S626_MULT_X0           0x0003  /* Supports no multipliers;
+                                        * fixed physical multiplier = 3. */
+#define S626_MULT_X1           0x0002  /* Supports multiplier x1;
+                                        * fixed physical multiplier = 2. */
+#define S626_MULT_X2           0x0001  /* Supports multipliers x1, x2;
+                                        * physical multipliers = 1 or 2. */
+#define S626_MULT_X4           0x0000  /* Supports multipliers x1, x2, x4;
+                                        * physical multipliers = 0, 1 or 2. */
+
+/* Sanity-check limits for parameters. */
+
+#define S626_NUM_COUNTERS      6       /* Maximum valid counter
+                                        * logical channel number. */
+#define S626_NUM_INTSOURCES    4
+#define S626_NUM_LATCHSOURCES  4
+#define S626_NUM_CLKMULTS      4
+#define S626_NUM_CLKSOURCES    4
+#define S626_NUM_CLKPOLS       2
+#define S626_NUM_INDEXPOLS     2
+#define S626_NUM_INDEXSOURCES  2
+#define S626_NUM_LOADTRIGS     4
+
+/* General macros for manipulating bitfields: */
+#define S626_MAKE(x, w, p)     (((x) & ((1 << (w)) - 1)) << (p))
+#define S626_UNMAKE(v, w, p)   (((v) >> (p)) & ((1 << (w)) - 1))
+
+/* Bit field positions in CRA: */
+#define S626_CRABIT_INDXSRC_B  14      /* B index source. */
+#define S626_CRABIT_CNTSRC_B   12      /* B counter source. */
+#define S626_CRABIT_INDXPOL_A  11      /* A index polarity. */
+#define S626_CRABIT_LOADSRC_A   9      /* A preload trigger. */
+#define S626_CRABIT_CLKMULT_A   7      /* A clock multiplier. */
+#define S626_CRABIT_INTSRC_A    5      /* A interrupt source. */
+#define S626_CRABIT_CLKPOL_A    4      /* A clock polarity. */
+#define S626_CRABIT_INDXSRC_A   2      /* A index source. */
+#define S626_CRABIT_CNTSRC_A    0      /* A counter source. */
+
+/* Bit field widths in CRA: */
+#define S626_CRAWID_INDXSRC_B  2
+#define S626_CRAWID_CNTSRC_B   2
+#define S626_CRAWID_INDXPOL_A  1
+#define S626_CRAWID_LOADSRC_A  2
+#define S626_CRAWID_CLKMULT_A  2
+#define S626_CRAWID_INTSRC_A   2
+#define S626_CRAWID_CLKPOL_A   1
+#define S626_CRAWID_INDXSRC_A  2
+#define S626_CRAWID_CNTSRC_A   2
+
+/* Bit field masks for CRA: */
+#define S626_CRAMSK_INDXSRC_B  S626_SET_CRA_INDXSRC_B(~0)
+#define S626_CRAMSK_CNTSRC_B   S626_SET_CRA_CNTSRC_B(~0)
+#define S626_CRAMSK_INDXPOL_A  S626_SET_CRA_INDXPOL_A(~0)
+#define S626_CRAMSK_LOADSRC_A  S626_SET_CRA_LOADSRC_A(~0)
+#define S626_CRAMSK_CLKMULT_A  S626_SET_CRA_CLKMULT_A(~0)
+#define S626_CRAMSK_INTSRC_A   S626_SET_CRA_INTSRC_A(~0)
+#define S626_CRAMSK_CLKPOL_A   S626_SET_CRA_CLKPOL_A(~0)
+#define S626_CRAMSK_INDXSRC_A  S626_SET_CRA_INDXSRC_A(~0)
+#define S626_CRAMSK_CNTSRC_A   S626_SET_CRA_CNTSRC_A(~0)
+
+/* Construct parts of the CRA value: */
+#define S626_SET_CRA_INDXSRC_B(x)      \
+       S626_MAKE((x), S626_CRAWID_INDXSRC_B, S626_CRABIT_INDXSRC_B)
+#define S626_SET_CRA_CNTSRC_B(x)       \
+       S626_MAKE((x), S626_CRAWID_CNTSRC_B, S626_CRABIT_CNTSRC_B)
+#define S626_SET_CRA_INDXPOL_A(x)      \
+       S626_MAKE((x), S626_CRAWID_INDXPOL_A, S626_CRABIT_INDXPOL_A)
+#define S626_SET_CRA_LOADSRC_A(x)      \
+       S626_MAKE((x), S626_CRAWID_LOADSRC_A, S626_CRABIT_LOADSRC_A)
+#define S626_SET_CRA_CLKMULT_A(x)      \
+       S626_MAKE((x), S626_CRAWID_CLKMULT_A, S626_CRABIT_CLKMULT_A)
+#define S626_SET_CRA_INTSRC_A(x)       \
+       S626_MAKE((x), S626_CRAWID_INTSRC_A, S626_CRABIT_INTSRC_A)
+#define S626_SET_CRA_CLKPOL_A(x)       \
+       S626_MAKE((x), S626_CRAWID_CLKPOL_A, S626_CRABIT_CLKPOL_A)
+#define S626_SET_CRA_INDXSRC_A(x)      \
+       S626_MAKE((x), S626_CRAWID_INDXSRC_A, S626_CRABIT_INDXSRC_A)
+#define S626_SET_CRA_CNTSRC_A(x)       \
+       S626_MAKE((x), S626_CRAWID_CNTSRC_A, S626_CRABIT_CNTSRC_A)
+
+/* Extract parts of the CRA value: */
+#define S626_GET_CRA_INDXSRC_B(v)      \
+       S626_UNMAKE((v), S626_CRAWID_INDXSRC_B, S626_CRABIT_INDXSRC_B)
+#define S626_GET_CRA_CNTSRC_B(v)       \
+       S626_UNMAKE((v), S626_CRAWID_CNTSRC_B, S626_CRABIT_CNTSRC_B)
+#define S626_GET_CRA_INDXPOL_A(v)      \
+       S626_UNMAKE((v), S626_CRAWID_INDXPOL_A, S626_CRABIT_INDXPOL_A)
+#define S626_GET_CRA_LOADSRC_A(v)      \
+       S626_UNMAKE((v), S626_CRAWID_LOADSRC_A, S626_CRABIT_LOADSRC_A)
+#define S626_GET_CRA_CLKMULT_A(v)      \
+       S626_UNMAKE((v), S626_CRAWID_CLKMULT_A, S626_CRABIT_CLKMULT_A)
+#define S626_GET_CRA_INTSRC_A(v)       \
+       S626_UNMAKE((v), S626_CRAWID_INTSRC_A, S626_CRABIT_INTSRC_A)
+#define S626_GET_CRA_CLKPOL_A(v)       \
+       S626_UNMAKE((v), S626_CRAWID_CLKPOL_A, S626_CRABIT_CLKPOL_A)
+#define S626_GET_CRA_INDXSRC_A(v)      \
+       S626_UNMAKE((v), S626_CRAWID_INDXSRC_A, S626_CRABIT_INDXSRC_A)
+#define S626_GET_CRA_CNTSRC_A(v)       \
+       S626_UNMAKE((v), S626_CRAWID_CNTSRC_A, S626_CRABIT_CNTSRC_A)
+
+/* Bit field positions in CRB: */
+#define S626_CRBBIT_INTRESETCMD        15      /* (w) Interrupt reset command. */
+#define S626_CRBBIT_CNTDIR_B   15      /* (r) B counter direction. */
+#define S626_CRBBIT_INTRESET_B 14      /* (w) B interrupt reset enable. */
+#define S626_CRBBIT_OVERDO_A   14      /* (r) A overflow routed to dig. out. */
+#define S626_CRBBIT_INTRESET_A 13      /* (w) A interrupt reset enable. */
+#define S626_CRBBIT_OVERDO_B   13      /* (r) B overflow routed to dig. out. */
+#define S626_CRBBIT_CLKENAB_A  12      /* A clock enable. */
+#define S626_CRBBIT_INTSRC_B   10      /* B interrupt source. */
+#define S626_CRBBIT_LATCHSRC    8      /* A/B latch source. */
+#define S626_CRBBIT_LOADSRC_B   6      /* B preload trigger. */
+#define S626_CRBBIT_CLEAR_B     7      /* B cleared when A overflows. */
+#define S626_CRBBIT_CLKMULT_B   3      /* B clock multiplier. */
+#define S626_CRBBIT_CLKENAB_B   2      /* B clock enable. */
+#define S626_CRBBIT_INDXPOL_B   1      /* B index polarity. */
+#define S626_CRBBIT_CLKPOL_B    0      /* B clock polarity. */
+
+/* Bit field widths in CRB: */
+#define S626_CRBWID_INTRESETCMD        1
+#define S626_CRBWID_CNTDIR_B   1
+#define S626_CRBWID_INTRESET_B 1
+#define S626_CRBWID_OVERDO_A   1
+#define S626_CRBWID_INTRESET_A 1
+#define S626_CRBWID_OVERDO_B   1
+#define S626_CRBWID_CLKENAB_A  1
+#define S626_CRBWID_INTSRC_B   2
+#define S626_CRBWID_LATCHSRC   2
+#define S626_CRBWID_LOADSRC_B  2
+#define S626_CRBWID_CLEAR_B    1
+#define S626_CRBWID_CLKMULT_B  2
+#define S626_CRBWID_CLKENAB_B  1
+#define S626_CRBWID_INDXPOL_B  1
+#define S626_CRBWID_CLKPOL_B   1
+
+/* Bit field masks for CRB: */
+#define S626_CRBMSK_INTRESETCMD        S626_SET_CRB_INTRESETCMD(~0)    /* (w) */
+#define S626_CRBMSK_CNTDIR_B   S626_CRBMSK_INTRESETCMD         /* (r) */
+#define S626_CRBMSK_INTRESET_B S626_SET_CRB_INTRESET_B(~0)     /* (w) */
+#define S626_CRBMSK_OVERDO_A   S626_CRBMSK_INTRESET_B          /* (r) */
+#define S626_CRBMSK_INTRESET_A S626_SET_CRB_INTRESET_A(~0)     /* (w) */
+#define S626_CRBMSK_OVERDO_B   S626_CRBMSK_INTRESET_A          /* (r) */
+#define S626_CRBMSK_CLKENAB_A  S626_SET_CRB_CLKENAB_A(~0)
+#define S626_CRBMSK_INTSRC_B   S626_SET_CRB_INTSRC_B(~0)
+#define S626_CRBMSK_LATCHSRC   S626_SET_CRB_LATCHSRC(~0)
+#define S626_CRBMSK_LOADSRC_B  S626_SET_CRB_LOADSRC_B(~0)
+#define S626_CRBMSK_CLEAR_B    S626_SET_CRB_CLEAR_B(~0)
+#define S626_CRBMSK_CLKMULT_B  S626_SET_CRB_CLKMULT_B(~0)
+#define S626_CRBMSK_CLKENAB_B  S626_SET_CRB_CLKENAB_B(~0)
+#define S626_CRBMSK_INDXPOL_B  S626_SET_CRB_INDXPOL_B(~0)
+#define S626_CRBMSK_CLKPOL_B   S626_SET_CRB_CLKPOL_B(~0)
+
+/* Interrupt reset control bits. */
+#define S626_CRBMSK_INTCTRL    (S626_CRBMSK_INTRESETCMD | \
+                                S626_CRBMSK_INTRESET_A | \
+                                S626_CRBMSK_INTRESET_B)
+
+/* Construct parts of the CRB value: */
+#define S626_SET_CRB_INTRESETCMD(x)    \
+       S626_MAKE((x), S626_CRBWID_INTRESETCMD, S626_CRBBIT_INTRESETCMD)
+#define S626_SET_CRB_INTRESET_B(x)     \
+       S626_MAKE((x), S626_CRBWID_INTRESET_B, S626_CRBBIT_INTRESET_B)
+#define S626_SET_CRB_INTRESET_A(x)     \
+       S626_MAKE((x), S626_CRBWID_INTRESET_A, S626_CRBBIT_INTRESET_A)
+#define S626_SET_CRB_CLKENAB_A(x)      \
+       S626_MAKE((x), S626_CRBWID_CLKENAB_A, S626_CRBBIT_CLKENAB_A)
+#define S626_SET_CRB_INTSRC_B(x)       \
+       S626_MAKE((x), S626_CRBWID_INTSRC_B, S626_CRBBIT_INTSRC_B)
+#define S626_SET_CRB_LATCHSRC(x)       \
+       S626_MAKE((x), S626_CRBWID_LATCHSRC, S626_CRBBIT_LATCHSRC)
+#define S626_SET_CRB_LOADSRC_B(x)      \
+       S626_MAKE((x), S626_CRBWID_LOADSRC_B, S626_CRBBIT_LOADSRC_B)
+#define S626_SET_CRB_CLEAR_B(x)        \
+       S626_MAKE((x), S626_CRBWID_CLEAR_B, S626_CRBBIT_CLEAR_B)
+#define S626_SET_CRB_CLKMULT_B(x)      \
+       S626_MAKE((x), S626_CRBWID_CLKMULT_B, S626_CRBBIT_CLKMULT_B)
+#define S626_SET_CRB_CLKENAB_B(x)      \
+       S626_MAKE((x), S626_CRBWID_CLKENAB_B, S626_CRBBIT_CLKENAB_B)
+#define S626_SET_CRB_INDXPOL_B(x)      \
+       S626_MAKE((x), S626_CRBWID_INDXPOL_B, S626_CRBBIT_INDXPOL_B)
+#define S626_SET_CRB_CLKPOL_B(x)       \
+       S626_MAKE((x), S626_CRBWID_CLKPOL_B, S626_CRBBIT_CLKPOL_B)
+
+/* Extract parts of the CRB value: */
+#define S626_GET_CRB_CNTDIR_B(v)       \
+       S626_UNMAKE((v), S626_CRBWID_CNTDIR_B, S626_CRBBIT_CNTDIR_B)
+#define S626_GET_CRB_OVERDO_A(v)       \
+       S626_UNMAKE((v), S626_CRBWID_OVERDO_A, S626_CRBBIT_OVERDO_A)
+#define S626_GET_CRB_OVERDO_B(v)       \
+       S626_UNMAKE((v), S626_CRBWID_OVERDO_B, S626_CRBBIT_OVERDO_B)
+#define S626_GET_CRB_CLKENAB_A(v)      \
+       S626_UNMAKE((v), S626_CRBWID_CLKENAB_A, S626_CRBBIT_CLKENAB_A)
+#define S626_GET_CRB_INTSRC_B(v)       \
+       S626_UNMAKE((v), S626_CRBWID_INTSRC_B, S626_CRBBIT_INTSRC_B)
+#define S626_GET_CRB_LATCHSRC(v)       \
+       S626_UNMAKE((v), S626_CRBWID_LATCHSRC, S626_CRBBIT_LATCHSRC)
+#define S626_GET_CRB_LOADSRC_B(v)      \
+       S626_UNMAKE((v), S626_CRBWID_LOADSRC_B, S626_CRBBIT_LOADSRC_B)
+#define S626_GET_CRB_CLEAR_B(v)        \
+       S626_UNMAKE((v), S626_CRBWID_CLEAR_B, S626_CRBBIT_CLEAR_B)
+#define S626_GET_CRB_CLKMULT_B(v)      \
+       S626_UNMAKE((v), S626_CRBWID_CLKMULT_B, S626_CRBBIT_CLKMULT_B)
+#define S626_GET_CRB_CLKENAB_B(v)      \
+       S626_UNMAKE((v), S626_CRBWID_CLKENAB_B, S626_CRBBIT_CLKENAB_B)
+#define S626_GET_CRB_INDXPOL_B(v)      \
+       S626_UNMAKE((v), S626_CRBWID_INDXPOL_B, S626_CRBBIT_INDXPOL_B)
+#define S626_GET_CRB_CLKPOL_B(v)       \
+       S626_UNMAKE((v), S626_CRBWID_CLKPOL_B, S626_CRBBIT_CLKPOL_B)
+
+/* Bit field positions for standardized SETUP structure: */
+#define S626_STDBIT_INTSRC     13
+#define S626_STDBIT_LATCHSRC   11
+#define S626_STDBIT_LOADSRC     9
+#define S626_STDBIT_INDXSRC     7
+#define S626_STDBIT_INDXPOL     6
+#define S626_STDBIT_ENCMODE     4
+#define S626_STDBIT_CLKPOL      3
+#define S626_STDBIT_CLKMULT     1
+#define S626_STDBIT_CLKENAB     0
+
+/* Bit field widths for standardized SETUP structure: */
+#define S626_STDWID_INTSRC     2
+#define S626_STDWID_LATCHSRC   2
+#define S626_STDWID_LOADSRC    2
+#define S626_STDWID_INDXSRC    1
+#define S626_STDWID_INDXPOL    1
+#define S626_STDWID_ENCMODE    2
+#define S626_STDWID_CLKPOL     1
+#define S626_STDWID_CLKMULT    2
+#define S626_STDWID_CLKENAB    1
+
+/* Bit field masks for standardized SETUP structure: */
+#define S626_STDMSK_INTSRC     S626_SET_STD_INTSRC(~0)
+#define S626_STDMSK_LATCHSRC   S626_SET_STD_LATCHSRC(~0)
+#define S626_STDMSK_LOADSRC    S626_SET_STD_LOADSRC(~0)
+#define S626_STDMSK_INDXSRC    S626_SET_STD_INDXSRC(~0)
+#define S626_STDMSK_INDXPOL    S626_SET_STD_INDXPOL(~0)
+#define S626_STDMSK_ENCMODE    S626_SET_STD_ENCMODE(~0)
+#define S626_STDMSK_CLKPOL     S626_SET_STD_CLKPOL(~0)
+#define S626_STDMSK_CLKMULT    S626_SET_STD_CLKMULT(~0)
+#define S626_STDMSK_CLKENAB    S626_SET_STD_CLKENAB(~0)
+
+/* Construct parts of standardized SETUP structure: */
+#define S626_SET_STD_INTSRC(x) \
+       S626_MAKE((x), S626_STDWID_INTSRC, S626_STDBIT_INTSRC)
+#define S626_SET_STD_LATCHSRC(x)       \
+       S626_MAKE((x), S626_STDWID_LATCHSRC, S626_STDBIT_LATCHSRC)
+#define S626_SET_STD_LOADSRC(x)        \
+       S626_MAKE((x), S626_STDWID_LOADSRC, S626_STDBIT_LOADSRC)
+#define S626_SET_STD_INDXSRC(x)        \
+       S626_MAKE((x), S626_STDWID_INDXSRC, S626_STDBIT_INDXSRC)
+#define S626_SET_STD_INDXPOL(x)        \
+       S626_MAKE((x), S626_STDWID_INDXPOL, S626_STDBIT_INDXPOL)
+#define S626_SET_STD_ENCMODE(x)        \
+       S626_MAKE((x), S626_STDWID_ENCMODE, S626_STDBIT_ENCMODE)
+#define S626_SET_STD_CLKPOL(x) \
+       S626_MAKE((x), S626_STDWID_CLKPOL, S626_STDBIT_CLKPOL)
+#define S626_SET_STD_CLKMULT(x)        \
+       S626_MAKE((x), S626_STDWID_CLKMULT, S626_STDBIT_CLKMULT)
+#define S626_SET_STD_CLKENAB(x)        \
+       S626_MAKE((x), S626_STDWID_CLKENAB, S626_STDBIT_CLKENAB)
+
+/* Extract parts of standardized SETUP structure: */
+#define S626_GET_STD_INTSRC(v) \
+       S626_UNMAKE((v), S626_STDWID_INTSRC, S626_STDBIT_INTSRC)
+#define S626_GET_STD_LATCHSRC(v)       \
+       S626_UNMAKE((v), S626_STDWID_LATCHSRC, S626_STDBIT_LATCHSRC)
+#define S626_GET_STD_LOADSRC(v)        \
+       S626_UNMAKE((v), S626_STDWID_LOADSRC, S626_STDBIT_LOADSRC)
+#define S626_GET_STD_INDXSRC(v)        \
+       S626_UNMAKE((v), S626_STDWID_INDXSRC, S626_STDBIT_INDXSRC)
+#define S626_GET_STD_INDXPOL(v)        \
+       S626_UNMAKE((v), S626_STDWID_INDXPOL, S626_STDBIT_INDXPOL)
+#define S626_GET_STD_ENCMODE(v)        \
+       S626_UNMAKE((v), S626_STDWID_ENCMODE, S626_STDBIT_ENCMODE)
+#define S626_GET_STD_CLKPOL(v) \
+       S626_UNMAKE((v), S626_STDWID_CLKPOL, S626_STDBIT_CLKPOL)
+#define S626_GET_STD_CLKMULT(v)        \
+       S626_UNMAKE((v), S626_STDWID_CLKMULT, S626_STDBIT_CLKMULT)
+#define S626_GET_STD_CLKENAB(v)        \
+       S626_UNMAKE((v), S626_STDWID_CLKENAB, S626_STDBIT_CLKENAB)
+
+#endif
index 9e964950a560ed92d9f37599d6138fd9c1a360b6..daee2f42bde0632c2cd05a38640ba1346a7bfeb6 100644 (file)
@@ -332,30 +332,44 @@ static int skel_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
        return i;
 }
 
-/* DIO devices are slightly special.  Although it is possible to
+/*
+ * DIO devices are slightly special. Although it is possible to
  * implement the insn_read/insn_write interface, it is much more
  * useful to applications if you implement the insn_bits interface.
- * This allows packed reading/writing of the DIO channels.  The
- * comedi core can convert between insn_bits and insn_read/write */
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write.
+ */
 static int skel_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       /*
+        * The insn data is a mask in data[0] and the new data
+        * in data[1], each channel cooresponding to a bit.
+        *
+        * The core provided comedi_dio_update_state() function can
+        * be used to handle the internal state update to DIO subdevices
+        * with <= 32 channels. This function will return '0' if the
+        * state does not change or the mask of the channels that need
+        * to be updated.
+        */
+       if (comedi_dio_update_state(s, data)) {
                /* Write out the new digital output lines */
-               /* outw(s->state,dev->iobase + SKEL_DIO); */
+               /* outw(s->state, dev->iobase + SKEL_DIO); */
        }
 
-       /* on return, data[1] contains the value of the digital
-        * input and output lines. */
-       /* data[1]=inw(dev->iobase + SKEL_DIO); */
-       /* or we could just return the software copy of the output values if
-        * it was a purely digital output subdevice */
-       /* data[1]=s->state; */
+       /*
+        * On return, data[1] contains the value of the digital
+        * input and output lines.
+        */
+       /* data[1] = inw(dev->iobase + SKEL_DIO); */
+
+       /*
+        * Or we could just return the software copy of the output
+        * values if it was a purely digital output subdevice.
+        */
+       /* data[1] = s->state; */
 
        return insn->n;
 }
index 11758a515c1bfed78ac7025b7f26d74a212368c6..df22a78d2b7e0879394953cb6f4987d77d6bc271 100644 (file)
@@ -46,51 +46,43 @@ Status: unknown
 #define PCMR  0xa3             /* Port C Mode Register                      */
 #define PCDR  0xa7             /* Port C Data Register                      */
 
-/* ------------------------------------------------------------------------- */
-/* The insn_bits interface allows packed reading/writing of DIO channels.    */
-/* The comedi core can convert between insn_bits and insn_read/write, so you */
-/* are able to use these instructions as well.                               */
-/* ------------------------------------------------------------------------- */
-
 static int dnp_dio_insn_bits(struct comedi_device *dev,
                             struct comedi_subdevice *s,
-                            struct comedi_insn *insn, unsigned int *data)
+                            struct comedi_insn *insn,
+                            unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data in data[1],   */
-       /* each channel cooresponding to a bit.                              */
-
-       /* Ports A and B are straight forward: each bit corresponds to an    */
-       /* output pin with the same order. Port C is different: bits 0...3   */
-       /* correspond to bits 4...7 of the output register (PCDR).           */
+       unsigned int mask;
+       unsigned int val;
 
-       if (data[0]) {
+       /*
+        * Ports A and B are straight forward: each bit corresponds to an
+        * output pin with the same order. Port C is different: bits 0...3
+        * correspond to bits 4...7 of the output register (PCDR).
+        */
 
+       mask = comedi_dio_update_state(s, data);
+       if (mask) {
                outb(PADR, CSCIR);
-               outb((inb(CSCDR)
-                     & ~(u8) (data[0] & 0x0000FF))
-                    | (u8) (data[1] & 0x0000FF), CSCDR);
+               outb(s->state & 0xff, CSCDR);
 
                outb(PBDR, CSCIR);
-               outb((inb(CSCDR)
-                     & ~(u8) ((data[0] & 0x00FF00) >> 8))
-                    | (u8) ((data[1] & 0x00FF00) >> 8), CSCDR);
+               outb((s->state >> 8) & 0xff, CSCDR);
 
                outb(PCDR, CSCIR);
-               outb((inb(CSCDR)
-                     & ~(u8) ((data[0] & 0x0F0000) >> 12))
-                    | (u8) ((data[1] & 0x0F0000) >> 12), CSCDR);
+               val = inb(CSCDR) & 0x0f;
+               outb(((s->state >> 12) & 0xf0) | val, CSCDR);
        }
 
-       /* on return, data[1] contains the value of the digital input lines. */
        outb(PADR, CSCIR);
-       data[0] = inb(CSCDR);
+       val = inb(CSCDR);
        outb(PBDR, CSCIR);
-       data[0] += inb(CSCDR) << 8;
+       val |= (inb(CSCDR) << 8);
        outb(PCDR, CSCIR);
-       data[0] += ((inb(CSCDR) & 0xF0) << 12);
+       val |= ((inb(CSCDR) & 0xf0) << 12);
 
-       return insn->n;
+       data[1] = val;
 
+       return insn->n;
 }
 
 static int dnp_dio_insn_config(struct comedi_device *dev,
index 701ad1a6939469d04df237ed71971006d7ed60ee..da1d501d9e4e64304e82f04a5f1e6e618f8d1647 100644 (file)
@@ -122,7 +122,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
 #define PWM_DEFAULT_PERIOD ((long)(1E9/100))
 
 /* Size of one A/D value */
-#define SIZEADIN          ((sizeof(int16_t)))
+#define SIZEADIN          ((sizeof(uint16_t)))
 
 /*
  * Size of the input-buffer IN BYTES
@@ -134,7 +134,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
 #define SIZEINSNBUF       16
 
 /* size of one value for the D/A converter: channel and value */
-#define SIZEDAOUT          ((sizeof(int8_t)+sizeof(int16_t)))
+#define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(uint16_t)))
 
 /*
  * Size of the output-buffer in bytes
@@ -195,15 +195,15 @@ struct usbdux_private {
        /* PWM period */
        unsigned int pwm_period;
        /* PWM internal delay for the GPIF in the FX2 */
-       int8_t pwm_delay;
+       uint8_t pwm_delay;
        /* size of the PWM buffer which holds the bit pattern */
        int pwm_buf_sz;
        /* input buffer for the ISO-transfer */
-       int16_t *in_buf;
+       uint16_t *in_buf;
        /* input buffer for single insn */
-       int16_t *insn_buf;
+       uint16_t *insn_buf;
 
-       int8_t ao_chanlist[USBDUX_NUM_AO_CHAN];
+       uint8_t ao_chanlist[USBDUX_NUM_AO_CHAN];
        unsigned int ao_readback[USBDUX_NUM_AO_CHAN];
 
        unsigned int high_speed:1;
@@ -225,7 +225,7 @@ struct usbdux_private {
        /* interval in frames/uframes */
        unsigned int ai_interval;
        /* commands */
-       int8_t *dux_commands;
+       uint8_t *dux_commands;
        struct semaphore sem;
 };
 
@@ -367,7 +367,7 @@ static void usbduxsub_ai_isoc_irq(struct urb *urb)
        n = s->async->cmd.chanlist_len;
        for (i = 0; i < n; i++) {
                unsigned int range = CR_RANGE(s->async->cmd.chanlist[i]);
-               int16_t val = le16_to_cpu(devpriv->in_buf[i]);
+               uint16_t val = le16_to_cpu(devpriv->in_buf[i]);
 
                /* bipolar data is two's-complement */
                if (comedi_range_is_bipolar(s, range))
@@ -415,7 +415,7 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb)
        struct comedi_device *dev = urb->context;
        struct comedi_subdevice *s = dev->write_subdev;
        struct usbdux_private *devpriv = dev->private;
-       int8_t *datap;
+       uint8_t *datap;
        int len;
        int ret;
        int i;
@@ -483,7 +483,7 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb)
                *datap++ = len;
                for (i = 0; i < s->async->cmd.chanlist_len; i++) {
                        unsigned int chan = devpriv->ao_chanlist[i];
-                       short val;
+                       unsigned short val;
 
                        ret = comedi_buf_get(s->async, &val);
                        if (ret < 0) {
@@ -649,14 +649,15 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev,
  * creates the ADC command for the MAX1271
  * range is the range value from comedi
  */
-static int8_t create_adc_command(unsigned int chan, int range)
+static uint8_t create_adc_command(unsigned int chan, unsigned int range)
 {
-       int8_t p = (range <= 1);
-       int8_t r = ((range % 2) == 0);
+       uint8_t p = (range <= 1);
+       uint8_t r = ((range % 2) == 0);
+
        return (chan << 4) | ((p == 1) << 2) | ((r == 1) << 3);
 }
 
-static int send_dux_commands(struct comedi_device *dev, int cmd_type)
+static int send_dux_commands(struct comedi_device *dev, unsigned int cmd_type)
 {
        struct usb_device *usb = comedi_to_usb_dev(dev);
        struct usbdux_private *devpriv = dev->private;
@@ -669,7 +670,7 @@ static int send_dux_commands(struct comedi_device *dev, int cmd_type)
                            &nsent, BULK_TIMEOUT);
 }
 
-static int receive_dux_commands(struct comedi_device *dev, int command)
+static int receive_dux_commands(struct comedi_device *dev, unsigned int command)
 {
        struct usb_device *usb = comedi_to_usb_dev(dev);
        struct usbdux_private *devpriv = dev->private;
@@ -879,7 +880,7 @@ static int usbdux_ao_insn_write(struct comedi_device *dev,
        struct usbdux_private *devpriv = dev->private;
        unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned int val = devpriv->ao_readback[chan];
-       int16_t *p = (int16_t *)&devpriv->dux_commands[2];
+       uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
        int ret = -EBUSY;
        int i;
 
@@ -1133,15 +1134,13 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev,
 {
 
        struct usbdux_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
        int ret;
 
        down(&devpriv->sem);
 
-       s->state &= ~mask;
-       s->state |= (bits & mask);
+       comedi_dio_update_state(s, data);
 
+       /* Always update the hardware. See the (*insn_config). */
        devpriv->dux_commands[1] = s->io_bits;
        devpriv->dux_commands[2] = s->state;
 
@@ -1200,7 +1199,7 @@ static int usbdux_counter_write(struct comedi_device *dev,
 {
        struct usbdux_private *devpriv = dev->private;
        unsigned int chan = CR_CHAN(insn->chanspec);
-       int16_t *p = (int16_t *)&devpriv->dux_commands[2];
+       uint16_t *p = (uint16_t *)&devpriv->dux_commands[2];
        int ret = 0;
        int i;
 
index c47f4087568fc0e4fae91c83433c49f9dba6c0eb..a5363ded3668329f60353b0462487195e842ff8f 100644 (file)
@@ -78,7 +78,7 @@
 #define USBDUXSIGMA_NUM_AO_CHAN                4
 
 /* Size of one A/D value */
-#define SIZEADIN          ((sizeof(int32_t)))
+#define SIZEADIN          ((sizeof(uint32_t)))
 
 /*
  * Size of the async input-buffer IN BYTES, the DIO state is transmitted
@@ -93,7 +93,7 @@
 #define NUMOUTCHANNELS    8
 
 /* size of one value for the D/A converter: channel and value */
-#define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(int16_t)))
+#define SIZEDAOUT          ((sizeof(uint8_t)+sizeof(uint16_t)))
 
 /*
  * Size of the output-buffer in bytes
@@ -157,11 +157,11 @@ struct usbduxsigma_private {
        /* size of the PWM buffer which holds the bit pattern */
        int pwm_buf_sz;
        /* input buffer for the ISO-transfer */
-       int32_t *in_buf;
+       uint32_t *in_buf;
        /* input buffer for single insn */
-       int8_t *insn_buf;
+       uint8_t *insn_buf;
 
-       int8_t ao_chanlist[USBDUXSIGMA_NUM_AO_CHAN];
+       uint8_t ao_chanlist[USBDUXSIGMA_NUM_AO_CHAN];
        unsigned int ao_readback[USBDUXSIGMA_NUM_AO_CHAN];
 
        unsigned high_speed:1;
@@ -224,7 +224,7 @@ static void usbduxsigma_ai_urb_complete(struct urb *urb)
        struct usbduxsigma_private *devpriv = dev->private;
        struct comedi_subdevice *s = dev->read_subdev;
        unsigned int dio_state;
-       int32_t val;
+       uint32_t val;
        int ret;
        int i;
 
@@ -421,7 +421,7 @@ static void usbduxsigma_ao_urb_complete(struct urb *urb)
                *datap++ = len;
                for (i = 0; i < len; i++) {
                        unsigned int chan = devpriv->ao_chanlist[i];
-                       short val;
+                       unsigned short val;
 
                        ret = comedi_buf_get(s->async, &val);
                        if (ret < 0) {
@@ -784,7 +784,7 @@ static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
        }
 
        for (i = 0; i < insn->n; i++) {
-               int32_t val;
+               uint32_t val;
 
                ret = usbduxsigma_receive_cmd(dev, USBDUXSIGMA_SINGLE_AD_CMD);
                if (ret < 0) {
@@ -793,7 +793,7 @@ static int usbduxsigma_ai_insn_read(struct comedi_device *dev,
                }
 
                /* 32 bits big endian from the A/D converter */
-               val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf) + 1)));
+               val = be32_to_cpu(*((uint32_t *)((devpriv->insn_buf) + 1)));
                val &= 0x00ffffff;      /* strip status byte */
                val ^= 0x00800000;      /* convert to unsigned */
 
@@ -1059,15 +1059,13 @@ static int usbduxsigma_dio_insn_bits(struct comedi_device *dev,
                                     unsigned int *data)
 {
        struct usbduxsigma_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
        int ret;
 
        down(&devpriv->sem);
 
-       s->state &= ~mask;
-       s->state |= (bits & mask);
+       comedi_dio_update_state(s, data);
 
+       /* Always update the hardware. See the (*insn_config). */
        devpriv->dux_commands[1] = s->io_bits & 0xff;
        devpriv->dux_commands[4] = s->state & 0xff;
        devpriv->dux_commands[2] = (s->io_bits >> 8) & 0xff;
@@ -1360,7 +1358,7 @@ static int usbduxsigma_getstatusinfo(struct comedi_device *dev, int chan)
                return ret;
 
        /* 32 bits big endian from the A/D converter */
-       val = be32_to_cpu(*((int32_t *)((devpriv->insn_buf)+1)));
+       val = be32_to_cpu(*((uint32_t *)((devpriv->insn_buf)+1)));
        val &= 0x00ffffff;      /* strip status byte */
        val ^= 0x00800000;      /* convert to unsigned */
 
index 06efa16b9af2377a0370952815d701dc344d51c4..933b01a0f03d4274e4f82ced6240a79f78b2c742 100644 (file)
@@ -462,9 +462,10 @@ static int vmk80xx_do_insn_bits(struct comedi_device *dev,
                                unsigned int *data)
 {
        struct vmk80xx_private *devpriv = dev->private;
-       unsigned char *rx_buf, *tx_buf;
+       unsigned char *rx_buf = devpriv->usb_rx_buf;
+       unsigned char *tx_buf = devpriv->usb_tx_buf;
        int reg, cmd;
-       int retval;
+       int ret;
 
        if (devpriv->model == VMK8061_MODEL) {
                reg = VMK8061_DO_REG;
@@ -476,37 +477,27 @@ static int vmk80xx_do_insn_bits(struct comedi_device *dev,
 
        down(&devpriv->limit_sem);
 
-       rx_buf = devpriv->usb_rx_buf;
-       tx_buf = devpriv->usb_tx_buf;
-
-       if (data[0]) {
-               tx_buf[reg] &= ~data[0];
-               tx_buf[reg] |= (data[0] & data[1]);
-
-               retval = vmk80xx_write_packet(dev, cmd);
-
-               if (retval)
+       if (comedi_dio_update_state(s, data)) {
+               tx_buf[reg] = s->state;
+               ret = vmk80xx_write_packet(dev, cmd);
+               if (ret)
                        goto out;
        }
 
        if (devpriv->model == VMK8061_MODEL) {
                tx_buf[0] = VMK8061_CMD_RD_DO;
-
-               retval = vmk80xx_read_packet(dev);
-
-               if (!retval) {
-                       data[1] = rx_buf[reg];
-                       retval = 2;
-               }
+               ret = vmk80xx_read_packet(dev);
+               if (ret)
+                       goto out;
+               data[1] = rx_buf[reg];
        } else {
-               data[1] = tx_buf[reg];
-               retval = 2;
+               data[1] = s->state;
        }
 
 out:
        up(&devpriv->limit_sem);
 
-       return retval;
+       return ret ? ret : insn->n;
 }
 
 static int vmk80xx_cnt_insn_read(struct comedi_device *dev,
index 5845e899ee806402d39dbfbe621aa7f2639818d2..043bd49843ffd4082b1303ca305a9842418293cf 100644 (file)
@@ -1517,7 +1517,7 @@ static void crystalhd_rx_isr(struct crystalhd_hw *hw, uint32_t intr_sts)
        uint32_t i, list_avail = 0;
        enum BC_STATUS comp_sts = BC_STS_NO_DATA;
        uint32_t y_err_sts, uv_err_sts, y_dn_sz = 0, uv_dn_sz = 0;
-       bool ret = 0;
+       bool ret = false;
 
        if (!hw) {
                BCMLOG_ERR("Invalid Arguments\n");
@@ -1852,7 +1852,7 @@ bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw)
 {
        uint32_t intr_sts = 0;
        uint32_t deco_intr = 0;
-       bool rc = 0;
+       bool rc = false;
 
        if (!adp || !hw->dev_started)
                return rc;
@@ -1865,7 +1865,7 @@ bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw)
 
        if (intr_sts) {
                /* let system know we processed interrupt..*/
-               rc = 1;
+               rc = true;
                hw->stats.dev_interrupts++;
        }
 
@@ -1886,7 +1886,7 @@ bool crystalhd_hw_interrupt(struct crystalhd_adp *adp, struct crystalhd_hw *hw)
                /* FIXME: jarod: No udelay? might this be
                 the real reason mini pci-e cards were stalling out? */
                bc_dec_reg_wr(adp, Stream2Host_Intr_Sts, 0);
-               rc = 1;
+               rc = true;
        }
 
        /* Rx interrupts */
index b17fbf8181cf424459eb3010a1ca4922117ec931..190b9b924368843f6f688a8ea32819ea329d8af9 100644 (file)
@@ -75,8 +75,9 @@ static int chd_dec_disable_int(struct crystalhd_adp *adp)
        return 0;
 }
 
-struct crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp,
-                                        bool isr)
+static struct
+crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp,
+                                          bool isr)
 {
        unsigned long flags = 0;
        struct crystalhd_ioctl_data *temp;
@@ -96,8 +97,8 @@ struct crystalhd_ioctl_data *chd_dec_alloc_iodata(struct crystalhd_adp *adp,
        return temp;
 }
 
-void chd_dec_free_iodata(struct crystalhd_adp *adp,
-                        struct crystalhd_ioctl_data *iodata, bool isr)
+static void chd_dec_free_iodata(struct crystalhd_adp *adp,
+                               struct crystalhd_ioctl_data *iodata, bool isr)
 {
        unsigned long flags = 0;
 
@@ -156,7 +157,7 @@ static int chd_dec_fetch_cdata(struct crystalhd_adp *adp,
        if (rc) {
                BCMLOG_ERR("failed to pull add_cdata sz:%x ua_off:%x\n",
                           io->add_cdata_sz, (unsigned int)ua_off);
-               kfree(io->add_cdata);
+               vfree(io->add_cdata);
                io->add_cdata = NULL;
                return -ENODATA;
        }
@@ -627,7 +628,7 @@ err:
 }
 
 #ifdef CONFIG_PM
-int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct crystalhd_adp *adp;
        struct crystalhd_ioctl_data *temp;
@@ -661,7 +662,7 @@ int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state)
        return 0;
 }
 
-int chd_dec_pci_resume(struct pci_dev *pdev)
+static int chd_dec_pci_resume(struct pci_dev *pdev)
 {
        struct crystalhd_adp *adp;
        enum BC_STATUS sts = BC_STS_SUCCESS;
index d71aea541811cab5e65ce0dca0e6079be84121a9..46a0d92173e0979e471eae2e467acbec2b573781 100644 (file)
@@ -145,10 +145,8 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster,
     /* Enable 8 out of 10 validation */
         /* t1RBOC enable(BOC:BitOriented Code) */
        pci_write_32((u_int32_t *) &comet->t1_rboc_ena, 0x00);
-       if (isT1mode)
-       {
-
-       /* IBCD cfg: aka Inband Code Detection ** loopback code length set to */
+       if (isT1mode) {
+               /* IBCD cfg: aka Inband Code Detection ** loopback code length set to */
                /* 6 bit down, 5 bit up (assert) */
                pci_write_32((u_int32_t *) &comet->ibcd_cfg, 0x04);
                /* line loopback activate pattern */
@@ -353,7 +351,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster,
        /* RLPS Configuration Status */
        pci_write_32((u_int32_t *) &comet->rlps_cfgsts, 0x11);
        if (isT1mode)
-                /* ? */
+               /* ? */
                pci_write_32((u_int32_t *) &comet->rlps_alos_thresh, 0x55);
        else
                /* ? */
@@ -452,7 +450,7 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table)
        volatile u_int32_t value;
 
        for (ramaddr = 0; ramaddr < 256; ramaddr++) {
-       /*** the following lines are per Errata 7, 2.5 ***/
+               /*** the following lines are per Errata 7, 2.5 ***/
                {
                /* Set up for a read operation */
                pci_write_32((u_int32_t *) &comet->rlps_eq_rwsel, 0x80);
index e06da4a6f6f640dc8c1876ecfb05b2644ea90798..03b9bb77a8097066c0018bce79f701f39e4bd66e 100644 (file)
@@ -338,7 +338,7 @@ typedef struct s_comet_reg comet_t;
 
 #ifdef __KERNEL__
 extern void
-init_comet (void *, comet_t *, u_int32_t, int, u_int8_t);
+init_comet(void *, comet_t *, u_int32_t, int, u_int8_t);
 #endif
 
 #endif                          /* _INC_COMET_H_ */
index 53e923701ae6d4099a27c7f6457b5830a4b4ba35..02b4f8f1aca5d6197407c693d34a6025a8b813a1 100644 (file)
@@ -157,7 +157,7 @@ prep_hdw_info (void)
         hi->pci_slot = 0xff;
         hi->pci_pin[0] = 0;
         hi->pci_pin[1] = 0;
-        hi->ndev = 0;
+        hi->ndev = NULL;
         hi->addr[0] = 0L;
         hi->addr[1] = 0L;
         hi->addr_mapped[0] = 0L;
@@ -309,7 +309,7 @@ c4hw_attach_all (void)
     if (!found)
     {
         pr_warning("No boards found\n");
-        return ENODEV;
+        return -ENODEV;
     }
     /* sanity check for consistent hardware found */
     for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
@@ -318,7 +318,7 @@ c4hw_attach_all (void)
         {
             pr_warning("%s: something very wrong with pci_get_device\n",
                        hi->devname);
-            return EIO;
+            return -EIO;
         }
     }
     /* bring board's memory regions on/line */
@@ -328,12 +328,12 @@ c4hw_attach_all (void)
             break;
         for (j = 0; j < 2; j++)
         {
-            if (request_mem_region (hi->addr[j], hi->len[j], hi->devname) == 0)
+           if (!request_mem_region (hi->addr[j], hi->len[j], hi->devname))
             {
                 pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n",
                            hi->devname, hi->addr[j], hi->len[j]);
                 cleanup_ioremap ();
-                return ENOMEM;
+                return -ENOMEM;
             }
             hi->addr_mapped[j] = (unsigned long) ioremap (hi->addr[j], hi->len[j]);
             if (!hi->addr_mapped[j])
@@ -341,7 +341,7 @@ c4hw_attach_all (void)
                 pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
                            hi->devname, hi->addr[j], hi->len[j]);
                 cleanup_ioremap ();
-                return ENOMEM;
+                return -ENOMEM;
             }
 #ifdef SBE_MAP_DEBUG
             pr_warning("%s: io remapped from phys %x to virt %x\n",
@@ -365,7 +365,7 @@ c4hw_attach_all (void)
                        hi->devname, i, hi->pci_slot);
             cleanup_devs ();
             cleanup_ioremap ();
-            return EIO;
+            return -EIO;
         }
         pci_set_master (hi->pdev[0]);
         pci_set_master (hi->pdev[1]);
index 142691c8d8d1c035b9b44b1b6900e117b79e312e..9b483739881a6acecaa7e09c10f0c6f5288f5183 100644 (file)
@@ -133,7 +133,7 @@ getuserbychan (int channum)
     mch_t      *ch;
 
     ch = c4_find_chan (channum);
-    return ch ? ch->user : 0;
+    return ch ? ch->user : NULL;
 }
 
 
@@ -230,7 +230,7 @@ c4_wq_port_init (mpi_t *pi)
             __func__, name, pi->portnum); /* RLD DEBUG */
 #endif
     if (!(pi->wq_port = create_singlethread_workqueue (name)))
-        return ENOMEM;
+        return -ENOMEM;
     return 0;                       /* success */
 }
 
@@ -245,7 +245,7 @@ c4_wq_port_cleanup (mpi_t *pi)
     {
         destroy_workqueue (pi->wq_port);        /* this also calls
                                                  * flush_workqueue() */
-        pi->wq_port = 0;
+        pi->wq_port = NULL;
     }
 }
 
@@ -420,7 +420,7 @@ create_chan (struct net_device *ndev, ci_t *ci,
     int         ret;
 
     if (c4_find_chan (cp->channum))
-        return 0;                   /* channel already exists */
+        return NULL;                   /* channel already exists */
 
     {
         struct c4_priv *priv;
@@ -430,14 +430,14 @@ create_chan (struct net_device *ndev, ci_t *ci,
         if (!priv)
         {
             pr_warning("%s: no memory for net_device !\n", ci->devname);
-            return 0;
+           return NULL;
         }
         dev = alloc_hdlcdev (priv);
         if (!dev)
         {
             pr_warning("%s: no memory for hdlc_device !\n", ci->devname);
             OS_kfree (priv);
-            return 0;
+           return NULL;
         }
         priv->ci = ci;
         priv->channum = cp->channum;
@@ -496,7 +496,7 @@ create_chan (struct net_device *ndev, ci_t *ci,
             pr_info("%s: create_chan[%d] registration error = %d.\n",
                     ci->devname, cp->channum, ret);
         free_netdev (dev);          /* cleanup */
-        return 0;                   /* failed to register */
+       return NULL;            /* failed to register */
     }
     return dev;
 }
@@ -744,7 +744,7 @@ do_deluser (struct net_device *ndev, int lockit)
         ch = c4_find_chan (channum);
         if (ch == NULL)
             return -ENOENT;
-        ch->user = 0;               /* will be freed, below */
+       ch->user = NULL;        /* will be freed, below */
     }
 
     if (lockit)
@@ -959,7 +959,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
     {
         pr_warning("%s: no memory for struct net_device !\n", hi->devname);
         error_flag = ENOMEM;
-        return 0;
+       return NULL;
     }
     ci = (ci_t *)(netdev_priv(ndev));
     ndev->irq = irq0;
@@ -970,7 +970,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
     c4_list = ci;
     ci->brdno = ci->next ? ci->next->brdno + 1 : 0;
 
-    if (CI == 0)
+    if (!CI)
         CI = ci;                    /* DEBUG, only board 0 usage */
 
     strcpy (ci->devname, hi->devname);
@@ -996,7 +996,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
         OS_kfree (netdev_priv(ndev));
         OS_kfree (ndev);
         error_flag = ENODEV;
-        return 0;
+       return NULL;
     }
     /*************************************************************
      *  int request_irq(unsigned int irq,
@@ -1022,7 +1022,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
         OS_kfree (netdev_priv(ndev));
         OS_kfree (ndev);
         error_flag = EIO;
-        return 0;
+       return NULL;
     }
 #ifdef CONFIG_SBE_PMCC4_NCOMM
     if (request_irq (irq1, &c4_ebus_interrupt, IRQF_SHARED, ndev->name, ndev))
@@ -1033,7 +1033,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
         OS_kfree (netdev_priv(ndev));
         OS_kfree (ndev);
         error_flag = EIO;
-        return 0;
+       return NULL;
     }
 #endif
 
@@ -1091,7 +1091,7 @@ c4_add_dev (hdw_info_t *hi, int brdno, unsigned long f0, unsigned long f1,
         free_irq (irq0, ndev);
         OS_kfree (netdev_priv(ndev));
         OS_kfree (ndev);
-        return 0;                   /* failure, error_flag is set */
+       return NULL;            /* failure, error_flag is set */
     }
     return ndev;
 }
index 52b6d7f5fd4758329cfa9cdec474175c1f92d405..0ba8c3ae673bd19cb86617a6b3ad0aea32ecf228 100644 (file)
@@ -745,8 +745,8 @@ musycc_init(ci_t *ci)
 #define INT_QUEUE_BOUNDARY  4
 
     regaddr = OS_kmalloc((INT_QUEUE_SIZE + 1) * sizeof(u_int32_t));
-    if (regaddr == 0)
-       return ENOMEM;
+    if (!regaddr)
+       return -ENOMEM;
     ci->iqd_p_saved = regaddr;      /* save orig value for free's usage */
     ci->iqd_p = (u_int32_t *) ((unsigned long) (regaddr + INT_QUEUE_BOUNDARY - 1) &
                               (~(INT_QUEUE_BOUNDARY - 1)));    /* this calculates
@@ -766,13 +766,13 @@ musycc_init(ci_t *ci)
 #define GROUP_BOUNDARY   0x800
 
        regaddr = OS_kmalloc(sizeof(struct musycc_groupr) + GROUP_BOUNDARY);
-       if (regaddr == 0) {
+       if (!regaddr) {
            for (gchan = 0; gchan < i; gchan++) {
                pi = &ci->port[gchan];
                OS_kfree(pi->reg);
-               pi->reg = 0;
+               pi->reg = NULL;
            }
-           return ENOMEM;
+           return -ENOMEM;
        }
        pi->regram_saved = regaddr; /* save orig value for free's usage */
        pi->regram = (struct musycc_groupr *) ((unsigned long) (regaddr + GROUP_BOUNDARY - 1) &
@@ -839,12 +839,12 @@ musycc_bh_tx_eom(mpi_t *pi, int gchan)
     volatile u_int32_t status;
 
     ch = pi->chan[gchan];
-    if (ch == 0 || ch->state != UP) {
+    if (!ch || ch->state != UP) {
        if (cxt1e1_log_level >= LOG_ERROR)
            pr_info("%s: intr: xmit EOM on uninitialized channel %d\n",
                    pi->up->devname, gchan);
     }
-    if (ch == 0 || ch->mdt == 0)
+    if (!ch || !ch->mdt)
        return;                     /* note: mdt==0 implies a malloc()
                                     * failure w/in chan_up() routine */
 
@@ -907,7 +907,7 @@ musycc_bh_tx_eom(mpi_t *pi, int gchan)
        ch->txd_irq_srv = md->snext;
 
        md->data = 0;
-       if (md->mem_token != 0) {
+       if (md->mem_token)      {
            /* upcount channel */
            atomic_sub(OS_mem_token_tlen(md->mem_token), &ch->tx_pending);
            /* upcount card */
@@ -931,7 +931,7 @@ musycc_bh_tx_eom(mpi_t *pi, int gchan)
 #endif                              /*** CONFIG_SBE_WAN256T3_NCOMM ***/
 
            OS_mem_token_free_irq(md->mem_token);
-           md->mem_token = 0;
+           md->mem_token = NULL;
        }
        md->status = 0;
 #ifdef RLD_TXFULL_DEBUG
@@ -1012,13 +1012,13 @@ musycc_bh_rx_eom(mpi_t *pi, int gchan)
     u_int32_t   error;
 
     ch = pi->chan[gchan];
-    if (ch == 0 || ch->state != UP) {
+    if (!ch || ch->state != UP) {
        if (cxt1e1_log_level > LOG_ERROR)
            pr_info("%s: intr: receive EOM on uninitialized channel %d\n",
                    pi->up->devname, gchan);
        return;
     }
-    if (ch->mdr == 0)
+    if (!ch->mdr)
        return;                     /* can this happen ? */
 
     for (;;) {
@@ -1566,18 +1566,18 @@ musycc_chan_down(ci_t *dummy, int channum)
     pi->regram->rmp[gchan] = 0;
     FLUSH_MEM_WRITE();
     for (i = 0; i < ch->txd_num; i++)
-       if (ch->mdt[i].mem_token != 0)
+       if (ch->mdt[i].mem_token)
            OS_mem_token_free(ch->mdt[i].mem_token);
 
     for (i = 0; i < ch->rxd_num; i++)
-       if (ch->mdr[i].mem_token != 0)
+       if (ch->mdr[i].mem_token)
            OS_mem_token_free(ch->mdr[i].mem_token);
 
     OS_kfree(ch->mdr);
-    ch->mdr = 0;
+    ch->mdr = NULL;
     ch->rxd_num = 0;
     OS_kfree(ch->mdt);
-    ch->mdt = 0;
+    ch->mdt = NULL;
     ch->txd_num = 0;
 
     musycc_update_timeslots(pi);
@@ -1746,7 +1746,7 @@ musycc_start_xmit(ci_t *ci, int channum, void *mem_token)
 #endif
            u |= (PADFILL_ENABLE | (ch->p.pad_fill_count << EXTRA_FLAGS));
        }
-       md->mem_token = len ? 0 : mem_token;    /* Fill in mds on last
+       md->mem_token = len ? NULL : mem_token;    /* Fill in mds on last
                                                 * segment, others set ZERO
                                                 * so that entire token is
                                                 * removed ONLY when ALL
index 2383c609bf39078bf2fe935957b105eb288ee00b..4028ea11c4423bc14096d80f7423bec5391b4297 100644 (file)
@@ -70,7 +70,7 @@ extern void *memset (void *s, int c, size_t n);
 #endif
 
 int         drvr_state = SBE_DRVR_INIT;
-ci_t       *c4_list = 0;
+ci_t       *c4_list = NULL;
 ci_t       *CI;                 /* dummy pointer to board ZEROE's data -
                                  * DEBUG USAGE */
 
@@ -119,7 +119,7 @@ c4_find_chan (int channum)
                         return ch;
                 }
             }
-    return 0;
+    return NULL;
 }
 
 
@@ -145,7 +145,7 @@ c4_new (void *hi)
         pr_warning("failed CI malloc, size %u.\n",
                    (unsigned int) sizeof (ci_t));
 
-    if (CI == 0)
+    if (!CI)
         CI = ci;                    /* DEBUG, only board 0 usage */
     return ci;
 }
@@ -831,7 +831,7 @@ c4_musycc_rw (ci_t *ci, struct c4_musycc_param *mcp)
 {
     mpi_t      *pi;
     volatile u_int32_t *dph;    /* hardware implemented register */
-    u_int32_t  *dpr = 0;        /* RAM image of registers for group command
+    u_int32_t *dpr = NULL;     /* RAM image of registers for group command
                                  * usage */
     int         offset = mcp->offset % 0x800;   /* group relative address
                                                  * offset, mcp->portnum is
@@ -1060,7 +1060,7 @@ c4_new_chan (ci_t *ci, int portnum, int channum, void *user)
     }
 
     /* save off interface assignments which bound a board */
-    if (ci->first_if == 0)          /* first channel registered is assumed to
+    if (!ci->first_if)         /* first channel registered is assumed to
                                      * be the lowest channel */
     {
         ci->first_if = ci->last_if = user;
@@ -1392,7 +1392,7 @@ c4_chan_up (ci_t *ci, int channum)
         md->status = HOST_TX_OWNED; /* Host owns TX descriptor ** CODING
                                      * NOTE: HOST_TX_OWNED = 0 so no need to
                                      * byteSwap */
-        md->mem_token = 0;
+        md->mem_token = NULL;
         md->data = 0;
         if (i == (txnum - 1))
         {
@@ -1448,10 +1448,10 @@ errfree:
         OS_mem_token_free (ch->mdr[i].mem_token);
     }
     OS_kfree (ch->mdt);
-    ch->mdt = 0;
+    ch->mdt = NULL;
     ch->txd_num = 0;
     OS_kfree (ch->mdr);
-    ch->mdr = 0;
+    ch->mdr = NULL;
     ch->rxd_num = 0;
     ch->state = DOWN;
     return ENOBUFS;
index 3c6d1c0fc6d69050c893a320781facd7419114d8..ba3ff3efe0634356cb7488aa61f168ac798a0223 100644 (file)
@@ -73,7 +73,7 @@ OS_mem_token_alloc (size_t size)
     if (!skb)
     {
         //pr_warning("no mem in OS_mem_token_alloc !\n");
-        return 0;
+        return NULL;
     }
     return skb;
 }
@@ -103,7 +103,7 @@ OS_mem_token_data (void *token)
 static inline void *
 OS_mem_token_next (void *token)
 {
-    return 0;
+    return NULL;
 }
 
 
index 87512a53f7203b8ea66335cbcc6cbb2801708260..81fa8a3a462cc6e216b052b455791dcc7b544207 100644 (file)
@@ -88,7 +88,7 @@ sbeCrc(u_int8_t *buffer,          /* data buffer to crc */
        u_int32_t initialCrc,      /* starting CRC */
        u_int32_t *result)
 {
-       u_int32_t     *tbl = 0;
+       u_int32_t     *tbl = NULL;
        u_int32_t      temp1, temp2, crc;
 
        /*
@@ -102,7 +102,7 @@ sbeCrc(u_int8_t *buffer,          /* data buffer to crc */
                genCrcTable(tbl);
 #else
                tbl = (u_int32_t *) OS_kmalloc(CRC_TABLE_ENTRIES * sizeof(u_int32_t));
-               if (tbl == 0) {
+               if (!tbl) {
                        *result = 0;   /* dummy up return value due to malloc
                                        * failure */
                        return;
index 791993fec96bac3eb6c232673282e7ce4194d593..6ec51bccceb11844270321aab3e7b256d54a1d8d 100644 (file)
@@ -22,7 +22,7 @@
 char       *
 sbeid_get_bdname (ci_t *ci)
 {
-    char       *np = 0;
+    char       *np = NULL;
 
     switch (ci->brd_id)
     {
index 9361dd8ce1255b6d7a4afa356bd477b219774296..353c001d3fbeec2f7f836c131a1181a2b3a9bf82 100644 (file)
@@ -44,7 +44,7 @@ void sbecom_proc_brd_cleanup(ci_t *ci)
 static void sbecom_proc_get_brdinfo(ci_t *ci, struct sbe_brd_info *bip)
 {
        hdw_info_t *hi = &hdw_info[ci->brdno];
-       u_int8_t *bsn = 0;
+       u_int8_t *bsn = NULL;
 
        switch (hi->promfmt)
        {
index ce9b15c71894726629805c4be41d12131bffa5a0..e1e5bfc9ad376316d1d9feb7ced1f3614562b4bc 100644 (file)
  */
 
 #define SBE_IOC_LOGLEVEL       _IOW(SBE_IOC_MAGIC, 0x00, int)
-#define SBE_IOC_CHAN_NEW       _IOW(SBE_IOC_MAGIC, 0x01,int)    /* unused */
-#define SBE_IOC_CHAN_UP        _IOW(SBE_IOC_MAGIC, 0x02,int)    /* unused */
-#define SBE_IOC_CHAN_DOWN      _IOW(SBE_IOC_MAGIC, 0x03,int)    /* unused */
-#define SBE_IOC_CHAN_GET       _IOWR(SBE_IOC_MAGIC,0x04, struct sbecom_chan_param)
+#define SBE_IOC_CHAN_NEW       _IOW(SBE_IOC_MAGIC, 0x01, int)    /* unused */
+#define SBE_IOC_CHAN_UP        _IOW(SBE_IOC_MAGIC, 0x02, int)    /* unused */
+#define SBE_IOC_CHAN_DOWN      _IOW(SBE_IOC_MAGIC, 0x03, int)    /* unused */
+#define SBE_IOC_CHAN_GET       _IOWR(SBE_IOC_MAGIC, 0x04, struct sbecom_chan_param)
 #define SBE_IOC_CHAN_SET       _IOW(SBE_IOC_MAGIC, 0x05, struct sbecom_chan_param)
-#define SBE_IOC_CHAN_GET_STAT  _IOWR(SBE_IOC_MAGIC,0x06, struct sbecom_chan_stats)
+#define SBE_IOC_CHAN_GET_STAT  _IOWR(SBE_IOC_MAGIC, 0x06, struct sbecom_chan_stats)
 #define SBE_IOC_CHAN_DEL_STAT  _IOW(SBE_IOC_MAGIC, 0x07, int)
 #define SBE_IOC_PORTS_ENABLE   _IOW(SBE_IOC_MAGIC, 0x0A, int)
-#define SBE_IOC_PORT_GET       _IOWR(SBE_IOC_MAGIC,0x0C, struct sbecom_port_param)
+#define SBE_IOC_PORT_GET       _IOWR(SBE_IOC_MAGIC, 0x0C, struct sbecom_port_param)
 #define SBE_IOC_PORT_SET       _IOW(SBE_IOC_MAGIC, 0x0D, struct sbecom_port_param)
-#define SBE_IOC_READ_VEC       _IOWR(SBE_IOC_MAGIC,0x10, struct sbecom_wrt_vec)
-#define SBE_IOC_WRITE_VEC      _IOWR(SBE_IOC_MAGIC,0x11, struct sbecom_wrt_vec)
+#define SBE_IOC_READ_VEC       _IOWR(SBE_IOC_MAGIC, 0x10, struct sbecom_wrt_vec)
+#define SBE_IOC_WRITE_VEC      _IOWR(SBE_IOC_MAGIC, 0x11, struct sbecom_wrt_vec)
 #define SBE_IOC_GET_SN         _IOR(SBE_IOC_MAGIC, 0x12, u_int32_t)
 #define SBE_IOC_RESET_DEV      _IOW(SBE_IOC_MAGIC, 0x13, int)
-#define SBE_IOC_FRAMER_GET     _IOWR(SBE_IOC_MAGIC,0x14, struct sbecom_framer_param)
+#define SBE_IOC_FRAMER_GET     _IOWR(SBE_IOC_MAGIC, 0x14, struct sbecom_framer_param)
 #define SBE_IOC_FRAMER_SET     _IOW(SBE_IOC_MAGIC, 0x15, struct sbecom_framer_param)
 #define SBE_IOC_CARD_GET       _IOR(SBE_IOC_MAGIC, 0x20, struct sbecom_card_param)
 #define SBE_IOC_CARD_SET       _IOW(SBE_IOC_MAGIC, 0x21, struct sbecom_card_param)
 #define SBE_IOC_CARD_DEL_STAT  _IO(SBE_IOC_MAGIC,  0x23)
 #define SBE_IOC_CARD_CHAN_STAT _IOR(SBE_IOC_MAGIC, 0x24, struct sbecom_chan_stats)
 #define SBE_IOC_CARD_BLINK     _IOW(SBE_IOC_MAGIC, 0x30, int)
-#define SBE_IOC_DRVINFO_GET    _IOWR(SBE_IOC_MAGIC,0x31, struct sbe_drv_info)
+#define SBE_IOC_DRVINFO_GET    _IOWR(SBE_IOC_MAGIC, 0x31, struct sbe_drv_info)
 #define SBE_IOC_BRDINFO_GET    _IOR(SBE_IOC_MAGIC, 0x32, struct sbe_brd_info)
-#define SBE_IOC_IID_GET        _IOWR(SBE_IOC_MAGIC,0x33, struct sbe_iid_info)
+#define SBE_IOC_IID_GET        _IOWR(SBE_IOC_MAGIC, 0x33, struct sbe_iid_info)
 #define SBE_IOC_BRDADDR_GET    _IOWR(SBE_IOC_MAGIC, 0x34, struct sbe_brd_addr)
 
 #ifdef NOT_YET_COMMON
-#define SBE_IOC_TSIOC_GET      _IOWR(SBE_IOC_MAGIC,0x16, struct wanc1t3_ts_param)
+#define SBE_IOC_TSIOC_GET      _IOWR(SBE_IOC_MAGIC, 0x16, struct wanc1t3_ts_param)
 #define SBE_IOC_TSIOC_SET      _IOW(SBE_IOC_MAGIC, 0x17, struct wanc1t3_ts_param)
 #endif
 
index 9f1fce157c77180260b758f0a1057d7959fd1dcb..3abe8d2bb748b3794c2c15430fb7a81b9b8464ab 100644 (file)
@@ -1,5 +1,3 @@
-EXTRA_CFLAGS += -DDG_NAME=\"dgap-1.3-16\" -DDG_PART=\"40002347_C\"
-
 obj-$(CONFIG_DGAP) += dgap.o
 
 
index f79e65cd1d51522aaf41fe8ecf4703263cc26773..271ac19257f9f32fd2aae6ee4c7ac180c02e6119 100644 (file)
@@ -35,7 +35,7 @@
 struct fepimg {
     int type;                          /* board type */
     int        len;                            /* length of image */
-    char fepimage[1];                  /* begining of image */
+    char fepimage[1];                  /* beginning of image */
 };
 
 struct downldio {
index 40ef785a04284d9a4c79633f2877a957b8c405dc..4c1515ee56e58a9e2d00f7385cb3494ac1a392bb 100644 (file)
 
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/delay.h>       /* For udelay */
 #include <linux/slab.h>
 #include <asm/uaccess.h>       /* For copy_from_user/copy_to_user */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
 #include <linux/sched.h>
-#endif
 
 #include "dgap_driver.h"
 #include "dgap_pci.h"
@@ -420,8 +416,7 @@ void dgap_cleanup_module(void)
                unregister_chrdev(DIGI_DGAP_MAJOR, "dgap");
        }
 
-       if (dgap_config_buf)
-               kfree(dgap_config_buf);
+       kfree(dgap_config_buf);
 
        for (i = 0; i < dgap_NumBoards; ++i) {
                dgap_remove_ports_sysfiles(dgap_Board[i]);
@@ -488,10 +483,8 @@ static void dgap_cleanup_board(struct board_t *brd)
                }
        }
 
-       if (brd->flipbuf)
-               kfree(brd->flipbuf);
-       if (brd->flipflagbuf)
-               kfree(brd->flipflagbuf);
+       kfree(brd->flipbuf);
+       kfree(brd->flipflagbuf);
 
        dgap_Board[brd->boardnum] = NULL;
 
index b1cf489a729c8d66327a15dfe3f1bef54733c272..7d631e80c00e8856dda9136cf14117250f4fc81d 100644 (file)
 /*
  * Driver identification, error and debugging statments
  *
- * In theory, you can change all occurances of "digi" in the next
+ * In theory, you can change all occurrences of "digi" in the next
  * three lines, and the driver printk's will all automagically change.
  *
  * APR((fmt, args, ...));      Always prints message
  * DPR((fmt, args, ...));      Only prints if DGAP_TRACER is defined at
  *                               compile time and dgap_debug!=0
  */
+#define        DG_NAME         "dgap-1.3-16"
+#define        DG_PART         "40002347_C"
+
 #define        PROCSTR         "dgap"                  /* /proc entries         */
 #define        DEVSTR          "/dev/dg/dgap"          /* /dev entries          */
 #define        DRVSTR          "dgap"                  /* Driver name string 
index 4464f02c9575731bca8de334cd44f0475814bdf1..794cf9db8b8308f63c494759bacbd101296552af 100644 (file)
@@ -134,7 +134,7 @@ int dgap_after_config_loaded(void)
                dgap_Board[i]->flipflagbuf = dgap_driver_kzmalloc(MYFLIPLEN, GFP_ATOMIC);
        }
 
-       return (rc);
+       return rc;
 }
 
 
@@ -150,14 +150,14 @@ static int dgap_usertoboard(struct board_t *brd, char *to_addr, char __user *fro
        int n = U2BSIZE;
 
        if (!brd || brd->magic != DGAP_BOARD_MAGIC)
-               return(-EFAULT);
+               return -EFAULT;
 
        while (len) {
                if (n > len)
                        n = len;
 
                if (copy_from_user((char *) &buf, from_addr, n) == -1 ) {
-                       return(-EFAULT);
+                       return -EFAULT;
                }
 
                /* Copy data from buffer to card memory */
@@ -169,7 +169,7 @@ static int dgap_usertoboard(struct board_t *brd, char *to_addr, char __user *fro
                from_addr += n;   
                n = U2BSIZE;
         }
-       return(0);
+       return 0;
 }
 
 
@@ -1155,20 +1155,20 @@ uint dgap_get_custom_baud(struct channel_t *ch)
        uint value = 0;
 
        if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
-               return (0);
+               return 0;
        }
 
        if (!ch->ch_bd || ch->ch_bd->magic != DGAP_BOARD_MAGIC) {
-               return (0);
+               return 0;
        }
 
        if (!(ch->ch_bd->bd_flags & BD_FEP5PLUS))
-               return (0);
+               return 0;
 
        vaddr = ch->ch_bd->re_map_membase;
 
        if (!vaddr)
-               return (0);
+               return 0;
 
        /*
         * Go get from fep mem, what the fep
@@ -1178,7 +1178,7 @@ uint dgap_get_custom_baud(struct channel_t *ch)
                (ch->ch_portnum * 0x28) + LINE_SPEED));
 
        value = readw(vaddr + offset);
-       return (value);
+       return value;
 }
 
 
@@ -1229,29 +1229,24 @@ int dgap_param(struct tty_struct *tty)
        uchar   mval;
        uchar   hflow;
 
-       if (!tty || tty->magic != TTY_MAGIC) {
-               return (-ENXIO);
-       }
+       if (!tty || tty->magic != TTY_MAGIC)
+               return -ENXIO;
 
        un = (struct un_t *) tty->driver_data;
-       if (!un || un->magic != DGAP_UNIT_MAGIC) {
-               return (-ENXIO);
-       }
+       if (!un || un->magic != DGAP_UNIT_MAGIC)
+               return -ENXIO;
 
        ch = un->un_ch;
-       if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) {
-               return (-ENXIO);
-       }
+       if (!ch || ch->magic != DGAP_CHANNEL_MAGIC)
+               return -ENXIO;
 
        bd = ch->ch_bd;
-       if (!bd || bd->magic != DGAP_BOARD_MAGIC) {
-               return (-ENXIO);
-       }
+       if (!bd || bd->magic != DGAP_BOARD_MAGIC)
+               return -ENXIO;
 
         bs = ch->ch_bs;
-       if (bs == 0) {
-               return (-ENXIO);
-       }
+       if (!bs)
+               return -ENXIO;
 
        DPR_PARAM(("param start: tdev: %x cflags: %x oflags: %x iflags: %x\n",
                ch->ch_tun.un_dev, ch->ch_c_cflag, ch->ch_c_oflag, ch->ch_c_iflag));
@@ -1558,7 +1553,7 @@ int dgap_param(struct tty_struct *tty)
 
        DPR_PARAM(("param finish\n"));
 
-       return (0);
+       return 0;
 }
 
 
@@ -1675,7 +1670,7 @@ static int dgap_event(struct board_t *bd)
        int             b1;
 
        if (!bd || bd->magic != DGAP_BOARD_MAGIC)
-               return (-ENXIO);
+               return -ENXIO;
 
        DGAP_LOCK(bd->bd_lock, lock_flags);
 
@@ -1683,7 +1678,7 @@ static int dgap_event(struct board_t *bd)
 
        if (!vaddr) {
                DGAP_UNLOCK(bd->bd_lock, lock_flags);
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        eaddr = (struct ev_t *) (vaddr + EVBUF);
@@ -1701,7 +1696,7 @@ static int dgap_event(struct board_t *bd)
                DPR_EVENT(("should be calling xxfail %d\n", __LINE__));
                /* Let go of board lock */
                DGAP_UNLOCK(bd->bd_lock, lock_flags);
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        /*
@@ -1949,5 +1944,5 @@ next:
        writew(tail, &(eaddr->ev_tail));
        DGAP_UNLOCK(bd->bd_lock, lock_flags);
 
-       return (0);
+       return 0;
 }               
index 3a12ba5e3c2ade2f34a2f376ec962e52c71ac74f..c9abc406a1e0cb5fe23f5b074e7f91607279d0b5 100644 (file)
@@ -211,7 +211,7 @@ struct bs_t {
 #define SIFLAG         0xea            /* Set UNIX iflags              */
 #define SFLOWC         0xeb            /* Set flow control characters  */
 #define STLOW          0xec            /* Set transmit low water mark  */
-#define RPAUSE         0xee            /* Pause recieve                */
+#define RPAUSE         0xee            /* Pause receive                */
 #define RRESUME                0xef            /* Resume receive               */  
 #define CHRESET                0xf0            /* Reset Channel                */
 #define BUFSETALL      0xf2            /* Set Tx & Rx buffer size avail*/
index 8ebf4b7373b74c8a696f919f1a10e189053b69d7..0dc2404922ff0a485bfe5e2b72e6e6898e3a32e2 100644 (file)
 #ifndef __DGAP_KCOMPAT_H
 #define __DGAP_KCOMPAT_H
 
-# ifndef KERNEL_VERSION
-#  define KERNEL_VERSION(a,b,c)  (((a) << 16) + ((b) << 8) + (c))
-# endif
-
-
 #if !defined(TTY_FLIPBUF_SIZE)
 # define TTY_FLIPBUF_SIZE 512
 #endif
                module_param(VAR, long, PERM); \
                MODULE_PARM_DESC(VAR, DESC);
 
-
-
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-
-
-
-
-/* NOTHING YET */
-
-
-
-
-# else
-
-
-
-# error "this driver does not support anything below the 2.6.27 kernel series."
-
-
-
-# endif
-
 #endif /* ! __DGAP_KCOMPAT_H */
index 5497e6de06088f21c88cc11a3b53b92ed46d584b..ff9d19449b43c1dc41d8b0a8ba0e9bdc3c2a0116 100644 (file)
@@ -904,7 +904,7 @@ int dgap_parsefile(char **in, int Remove)
 /*
  * dgap_sindex: much like index(), but it looks for a match of any character in
  * the group, and returns that position.  If the first character is a ^, then
- * this will match the first occurence not in that group.
+ * this will match the first occurrence not in that group.
  */
 static char *dgap_sindex (char *string, char *group)
 {
@@ -1013,8 +1013,10 @@ static void dgap_err(char *s)
 static struct cnode *dgap_newnode(int t)
 {
        struct cnode *n;
-       if ( (n = (struct cnode *) kmalloc(sizeof(struct cnode ), GFP_ATOMIC) ) != NULL) {
-               memset( (char *)n, 0, sizeof(struct cnode ) );
+
+       n = kmalloc(sizeof(struct cnode), GFP_ATOMIC);
+       if (n != NULL) {
+               memset((char *)n, 0, sizeof(struct cnode));
                n->type = t;
        }
        return(n);
@@ -1150,7 +1152,7 @@ uint dgap_config_get_altpin(struct board_t *bd)
 
 /*
  * Given a specific type of board, if found, detached link and 
- * returns the first occurance in the list.
+ * returns the first occurrence in the list.
  */
 struct cnode *dgap_find_config(int type, int bus, int slot)
 {
index 94da06fcf7e9b869a9de127f3465660745905bf1..7f4ec9a1829398f87c2bd58a3a3be339c1151b80 100644 (file)
@@ -395,7 +395,7 @@ static ssize_t dgap_tty_state_show(struct device *d, struct device_attribute *at
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -420,7 +420,7 @@ static ssize_t dgap_tty_baud_show(struct device *d, struct device_attribute *att
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -445,7 +445,7 @@ static ssize_t dgap_tty_msignals_show(struct device *d, struct device_attribute
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -479,7 +479,7 @@ static ssize_t dgap_tty_iflag_show(struct device *d, struct device_attribute *at
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -504,7 +504,7 @@ static ssize_t dgap_tty_cflag_show(struct device *d, struct device_attribute *at
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -529,7 +529,7 @@ static ssize_t dgap_tty_oflag_show(struct device *d, struct device_attribute *at
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -554,7 +554,7 @@ static ssize_t dgap_tty_lflag_show(struct device *d, struct device_attribute *at
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -579,7 +579,7 @@ static ssize_t dgap_tty_digi_flag_show(struct device *d, struct device_attribute
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -604,7 +604,7 @@ static ssize_t dgap_tty_rxcount_show(struct device *d, struct device_attribute *
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -629,7 +629,7 @@ static ssize_t dgap_tty_txcount_show(struct device *d, struct device_attribute *
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
@@ -661,7 +661,7 @@ static ssize_t dgap_tty_name_show(struct device *d, struct device_attribute *att
 
        if (!d)
                return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGAP_UNIT_MAGIC)
                return (0);
        ch = un->un_ch;
index b906db30b617678a648f6a910800a98a7c95c6be..2a7a37298da4456ddbcab91a81b7cb6d407d5dcd 100644 (file)
@@ -249,7 +249,7 @@ int dgap_tty_register(struct board_t *brd)
 
        /*
         * If we're doing transparent print, we have to do all of the above
-        * again, seperately so we don't get the LD confused about what major
+        * again, separately so we don't get the LD confused about what major
         * we are when we get into the dgap_tty_open() routine.
         */
        brd->PrintDriver = alloc_tty_driver(MAXPORTS);
@@ -497,10 +497,8 @@ int dgap_tty_init(struct board_t *brd)
  */
 void dgap_tty_post_uninit(void)
 {
-       if (dgap_TmpWriteBuf) {
-               kfree(dgap_TmpWriteBuf);
-               dgap_TmpWriteBuf = NULL;
-       }
+       kfree(dgap_TmpWriteBuf);
+       dgap_TmpWriteBuf = NULL;
 }
 
 
@@ -522,10 +520,8 @@ void dgap_tty_uninit(struct board_t *brd)
                        tty_unregister_device(brd->SerialDriver, i);
                }
                tty_unregister_driver(brd->SerialDriver);
-               if (brd->SerialDriver->ttys) {
-                       kfree(brd->SerialDriver->ttys);
-                       brd->SerialDriver->ttys = NULL;
-               }
+               kfree(brd->SerialDriver->ttys);
+               brd->SerialDriver->ttys = NULL;
                put_tty_driver(brd->SerialDriver);
                brd->dgap_Major_Serial_Registered = FALSE;
        }
@@ -538,10 +534,8 @@ void dgap_tty_uninit(struct board_t *brd)
                        tty_unregister_device(brd->PrintDriver, i);
                }
                tty_unregister_driver(brd->PrintDriver);
-               if (brd->PrintDriver->ttys) {
-                       kfree(brd->PrintDriver->ttys);
-                       brd->PrintDriver->ttys = NULL;
-               }
+               kfree(brd->PrintDriver->ttys);
+               brd->PrintDriver->ttys = NULL;
                put_tty_driver(brd->PrintDriver);
                brd->dgap_Major_TransparentPrint_Registered = FALSE;
        }
@@ -601,7 +595,7 @@ static void dgap_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *b
                /*
                 *  Loop while data remains.
                 */
-               while (nbuf > 0 && ch->ch_sniff_buf != 0) {
+               while (nbuf > 0 && ch->ch_sniff_buf) {
                        /*
                         *  Determine the amount of available space left in the
                         *  buffer.  If there's none, wait until some appears.
@@ -1069,7 +1063,7 @@ static int dgap_tty_open(struct tty_struct *tty, struct file *file)
 
        DGAP_LOCK(brd->bd_lock, lock_flags);
 
-       /* The wait above should guarentee this cannot happen */
+       /* The wait above should guarantee this cannot happen */
        if (brd->state != BOARD_READY) {
                DGAP_UNLOCK(brd->bd_lock, lock_flags);
                return -ENXIO;
@@ -1113,9 +1107,10 @@ static int dgap_tty_open(struct tty_struct *tty, struct file *file)
                MAJOR(tty_devnum(tty)), MINOR(tty_devnum(tty)), un, brd->name));
 
        /*
-        * Error if channel info pointer is 0.
+        * Error if channel info pointer is NULL.
         */
-       if ((bs = ch->ch_bs) == 0) {
+       bs = ch->ch_bs;
+       if (!bs) {
                DGAP_UNLOCK(ch->ch_lock, lock_flags2);
                DGAP_UNLOCK(brd->bd_lock, lock_flags);
                DPR_OPEN(("%d BS is 0!\n", __LINE__));
@@ -3513,10 +3508,6 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                        return(-EINVAL);
                }
 
-               DGAP_UNLOCK(ch->ch_lock, lock_flags2);
-               DGAP_UNLOCK(bd->bd_lock, lock_flags);
-               return(-ENOIOCTLCMD);
-
        case DIGI_GETA:
                /* get information for ditty */
                DGAP_UNLOCK(ch->ch_lock, lock_flags2);
@@ -3586,12 +3577,4 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                return(-ENOIOCTLCMD);
        }
-
-       DGAP_UNLOCK(ch->ch_lock, lock_flags2);
-       DGAP_UNLOCK(bd->bd_lock, lock_flags);
-
-       DPR_IOCTL(("dgap_tty_ioctl end - cmd %s (%x), arg %lx\n", 
-               dgap_ioctl_name(cmd), cmd, arg));
-                        
-       return(0);
 }
index 651e2e5e93c7780765d0f2c9a9bc6c8d91f6d20f..bcea4f734a329c6a18de37d2e67eba2b7bc9fc92 100644 (file)
@@ -203,9 +203,9 @@ struct shrink_buf_struct {
        unsigned long   shrink_buf_vaddr;       /* Virtual address of board */
        unsigned long   shrink_buf_phys;        /* Physical address of board */
        unsigned long   shrink_buf_bseg;        /* Amount of board memory */
-       unsigned long   shrink_buf_hseg;        /* '186 Begining of Dual-Port */
+       unsigned long   shrink_buf_hseg;        /* '186 Beginning of Dual-Port */
 
-       unsigned long   shrink_buf_lseg;        /* '186 Begining of freed memory                                                */ 
+       unsigned long   shrink_buf_lseg;        /* '186 Beginning of freed memory                                               */ 
        unsigned long   shrink_buf_mseg;        /* Linear address from start of
                                                   dual-port were freed memory
                                                   begins, host viewpoint. */
index 57dfd6bafcf69a2ba3450b65a43c858607a73bc3..638c5da43c85fbad924797369c8349582aedd321 100644 (file)
@@ -52,7 +52,7 @@ char          *pgm;
 void           myperror();
 
 /*
-**  This structure is used to keep track of the diferent images available
+**  This structure is used to keep track of the different images available
 **  to give to the driver.  It is arranged so that the things that are
 **  constants or that have defaults are first inthe strucutre to simplify
 **  the table of initializers.
@@ -789,7 +789,7 @@ int main(int argc, char **argv)
 /*
 ** myperror()
 **
-**  Same as normal perror(), but places the program name at the begining
+**  Same as normal perror(), but places the program name at the beginning
 **  of the message.
 */
 void myperror(char *s)
index 117e158082402ddc5b32ace5dfcadc3201300e2d..fdc1aabc7fdeb649085a746c4c8f61c54e69425a 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/sched.h>       /* For jiffies, task states */
 #include <linux/interrupt.h>   /* For tasklet and interrupt structs/defines */
 #include <linux/delay.h>       /* For udelay */
-#include <asm/io.h>            /* For read[bwl]/write[bwl] */
+#include <linux/io.h>          /* For read[bwl]/write[bwl] */
 #include <linux/serial.h>      /* For struct async_serial */
 #include <linux/serial_reg.h>  /* For the various UART offsets */
 #include <linux/pci.h>
@@ -43,7 +43,7 @@
 #include "dgnc_tty.h"
 #include "dgnc_trace.h"
 
-static inline void cls_parse_isr(struct board_t *brd, uint port);
+static inline void cls_parse_isr(struct dgnc_board *brd, uint port);
 static inline void cls_clear_break(struct channel_t *ch, int force);
 static inline void cls_set_cts_flow_control(struct channel_t *ch);
 static inline void cls_set_rts_flow_control(struct channel_t *ch);
@@ -53,7 +53,7 @@ static inline void cls_set_no_output_flow_control(struct channel_t *ch);
 static inline void cls_set_no_input_flow_control(struct channel_t *ch);
 static void cls_parse_modem(struct channel_t *ch, uchar signals);
 static void cls_tasklet(unsigned long data);
-static void cls_vpd(struct board_t *brd);
+static void cls_vpd(struct dgnc_board *brd);
 static void cls_uart_init(struct channel_t *ch);
 static void cls_uart_off(struct channel_t *ch);
 static int cls_drain(struct tty_struct *tty, uint seconds);
@@ -393,7 +393,7 @@ static inline void cls_clear_break(struct channel_t *ch, int force)
 
 
 /* Parse the ISR register for the specific port */
-static inline void cls_parse_isr(struct board_t *brd, uint port)
+static inline void cls_parse_isr(struct dgnc_board *brd, uint port)
 {
        struct channel_t *ch;
        uchar isr = 0;
@@ -417,9 +417,8 @@ static inline void cls_parse_isr(struct board_t *brd, uint port)
                isr = readb(&ch->ch_cls_uart->isr_fcr);
 
                /* Bail if no pending interrupt on port */
-               if (isr & UART_IIR_NO_INT)  {
+               if (isr & UART_IIR_NO_INT)
                        break;
-               }
 
                DPR_INTR(("%s:%d port: %x isr: %x\n", __FILE__, __LINE__, port, isr));
 
@@ -444,9 +443,8 @@ static inline void cls_parse_isr(struct board_t *brd, uint port)
                }
 
                /* Received Xoff signal/Special character */
-               if (isr & UART_IIR_XOFF) {
+               if (isr & UART_IIR_XOFF)
                        /* Empty */
-               }
 
                /* CTS/RTS change of state */
                if (isr & UART_IIR_CTSRTS) {
@@ -477,28 +475,24 @@ static void cls_param(struct tty_struct *tty)
        uchar uart_ier = 0;
         uint baud = 9600;
        int quot = 0;
-        struct board_t *bd;
+        struct dgnc_board *bd;
        struct channel_t *ch;
         struct un_t   *un;
 
-       if (!tty || tty->magic != TTY_MAGIC) {
+       if (!tty || tty->magic != TTY_MAGIC)
                return;
-       }
 
        un = (struct un_t *) tty->driver_data;
-       if (!un || un->magic != DGNC_UNIT_MAGIC) {
+       if (!un || un->magic != DGNC_UNIT_MAGIC)
                return;
-       }
 
        ch = un->un_ch;
-       if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) {
+       if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
                return;
-       }
 
        bd = ch->ch_bd;
-       if (!bd || bd->magic != DGNC_BOARD_MAGIC) {
+       if (!bd || bd->magic != DGNC_BOARD_MAGIC)
                return;
-       }
 
        DPR_PARAM(("param start: tdev: %x cflags: %x oflags: %x iflags: %x\n",
                ch->ch_tun.un_dev, ch->ch_c_cflag, ch->ch_c_oflag, ch->ch_c_iflag));
@@ -725,7 +719,7 @@ static void cls_param(struct tty_struct *tty)
  */
 static void cls_tasklet(unsigned long data)
 {
-        struct board_t *bd = (struct board_t *) data;
+        struct dgnc_board *bd = (struct dgnc_board *) data;
        struct channel_t *ch;
        ulong  lock_flags;
        int i;
@@ -802,7 +796,7 @@ static void cls_tasklet(unsigned long data)
  */
 static irqreturn_t cls_intr(int irq, void *voidbrd)
 {
-       struct board_t *brd = (struct board_t *) voidbrd;
+       struct dgnc_board *brd = (struct dgnc_board *) voidbrd;
        uint i = 0;
        uchar poll_reg;
        unsigned long lock_flags;
@@ -976,17 +970,17 @@ static int cls_drain(struct tty_struct *tty, uint seconds)
        int rc = 0;
 
        if (!tty || tty->magic != TTY_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        un = (struct un_t *) tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -1002,7 +996,7 @@ static int cls_drain(struct tty_struct *tty, uint seconds)
        if (rc)
                DPR_IOCTL(("%d Drain - User ctrl c'ed\n", __LINE__));
 
-        return (rc);
+        return rc;
 }
 
 
@@ -1305,9 +1299,8 @@ static uint cls_get_uart_bytes_left(struct channel_t *ch)
 
        /* Determine whether the Transmitter is empty or not */
        if (!(lsr & UART_LSR_TEMT)) {
-               if (ch->ch_flags & CH_TX_FIFO_EMPTY) {
+               if (ch->ch_flags & CH_TX_FIFO_EMPTY)
                        tasklet_schedule(&ch->ch_bd->helper_tasklet);
-               }
                left = 1;
        }
        else {
@@ -1378,7 +1371,7 @@ static void cls_send_immediate_char(struct channel_t *ch, unsigned char c)
        writeb(c, &ch->ch_cls_uart->txrx);
 }
 
-static void cls_vpd(struct board_t *brd)
+static void cls_vpd(struct dgnc_board *brd)
 {
         ulong           vpdbase;        /* Start of io base of the card */
         u8 __iomem           *re_map_vpdbase;/* Remapped memory of the card */
index 71d2b83cc3a12e365823df2e40fd176ac26120ef..c204266cb69fc7ab8a1ec3c2284878bfdaee0232 100644 (file)
 
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
 #include <linux/sched.h>
-#endif
-
 #include "dgnc_driver.h"
 #include "dgnc_pci.h"
 #include "dpacompat.h"
@@ -71,16 +66,16 @@ PARM_INT(trcbuf_size,       0x100000,       0644,   "Debugging trace buffer size.");
  *
  */
 static int             dgnc_start(void);
-static int             dgnc_finalize_board_init(struct board_t *brd);
+static int             dgnc_finalize_board_init(struct dgnc_board *brd);
 static void            dgnc_init_globals(void);
 static int             dgnc_found_board(struct pci_dev *pdev, int id);
-static void            dgnc_cleanup_board(struct board_t *brd);
+static void            dgnc_cleanup_board(struct dgnc_board *brd);
 static void            dgnc_poll_handler(ulong dummy);
 static int             dgnc_init_pci(void);
 static int             dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static void            dgnc_remove_one(struct pci_dev *dev);
 static int             dgnc_probe1(struct pci_dev *pdev, int card_type);
-static void            dgnc_do_remap(struct board_t *brd);
+static void            dgnc_do_remap(struct dgnc_board *brd);
 
 /* Driver load/unload functions */
 int            dgnc_init_module(void);
@@ -106,7 +101,7 @@ static struct file_operations dgnc_BoardFops =
  * Globals
  */
 uint                   dgnc_NumBoards;
-struct board_t         *dgnc_Board[MAXBOARDS];
+struct dgnc_board              *dgnc_Board[MAXBOARDS];
 DEFINE_SPINLOCK(dgnc_global_lock);
 int                    dgnc_driver_state = DRIVER_INITIALIZED;
 ulong                  dgnc_poll_counter;
@@ -225,7 +220,7 @@ int dgnc_init_module(void)
        rc = dgnc_start();
 
        if (rc < 0) {
-               return(rc);
+               return rc;
        }
 
        /*
@@ -250,7 +245,7 @@ int dgnc_init_module(void)
        }
 
        DPR_INIT(("Finished init_module. Returning %d\n", rc));
-       return (rc);
+       return rc;
 }
 
 
@@ -286,21 +281,14 @@ static int dgnc_start(void)
                        if (rc <= 0) {
                                APR(("Can't register dgnc driver device (%d)\n", rc));
                                rc = -ENXIO;
-                               return(rc);
+                               return rc;
                        }
                        dgnc_Major = rc;
 
                        dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
-                       device_create_drvdata(dgnc_class, NULL,
-                               MKDEV(dgnc_Major, 0),
-                               NULL, "dgnc_mgmt");
-#else
                        device_create(dgnc_class, NULL,
                                MKDEV(dgnc_Major, 0),
                                NULL, "dgnc_mgmt");
-#endif
-
                        dgnc_Major_Control_Registered = TRUE;
                }
 
@@ -311,7 +299,7 @@ static int dgnc_start(void)
 
                if (rc < 0) {
                        APR(("tty preinit - not enough memory (%d)\n", rc));
-                       return(rc);
+                       return rc;
                }
 
                /* Start the poller */
@@ -328,7 +316,7 @@ static int dgnc_start(void)
                dgnc_driver_state = DRIVER_READY;
        }
 
-       return(rc);
+       return rc;
 }
 
 /*
@@ -418,7 +406,7 @@ void dgnc_cleanup_module(void)
  *
  * Free all the memory associated with a board
  */
-static void dgnc_cleanup_board(struct board_t *brd)
+static void dgnc_cleanup_board(struct dgnc_board *brd)
 {
        int i = 0;
 
@@ -491,7 +479,7 @@ static void dgnc_cleanup_board(struct board_t *brd)
  */
 static int dgnc_found_board(struct pci_dev *pdev, int id)
 {
-       struct board_t *brd;
+       struct dgnc_board *brd;
        unsigned int pci_irq;
        int i = 0;
        int rc = 0;
@@ -499,19 +487,16 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
 
        /* get the board structure and prep it */
        brd = dgnc_Board[dgnc_NumBoards] =
-       (struct board_t *) kzalloc(sizeof(struct board_t), GFP_KERNEL);
-       if (!brd) {
-               APR(("memory allocation for board structure failed\n"));
-               return(-ENOMEM);
-       }
+               kzalloc(sizeof(*brd), GFP_KERNEL);
+       if (!brd) 
+               return -ENOMEM;
 
        /* make a temporary message buffer for the boot messages */
        brd->msgbuf = brd->msgbuf_head =
-               (char *) kzalloc(sizeof(char) * 8192, GFP_KERNEL);
+               kzalloc(sizeof(u8) * 8192, GFP_KERNEL);
        if (!brd->msgbuf) {
                kfree(brd);
-               APR(("memory allocation for board msgbuf failed\n"));
-               return(-ENOMEM);
+               return -ENOMEM;
        }
 
        /* store the info for the board we've found */
@@ -663,7 +648,7 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
 
        default:
                APR(("Did not find any compatible Neo or Classic PCI boards in system.\n"));
-               return (-ENXIO);
+               return -ENXIO;
 
        }
 
@@ -725,22 +710,22 @@ static int dgnc_found_board(struct pci_dev *pdev, int id)
 
        wake_up_interruptible(&brd->state_wait);
 
-       return(0);
+       return 0;
 
 failed:
 
-       return (-ENXIO);
+       return -ENXIO;
 
 }
 
 
-static int dgnc_finalize_board_init(struct board_t *brd) {
+static int dgnc_finalize_board_init(struct dgnc_board *brd) {
        int rc = 0;
 
        DPR_INIT(("dgnc_finalize_board_init() - start\n"));
 
        if (!brd || brd->magic != DGNC_BOARD_MAGIC)
-               return(-ENODEV);
+               return -ENODEV;
 
        DPR_INIT(("dgnc_finalize_board_init() - start #2\n"));
 
@@ -756,13 +741,13 @@ static int dgnc_finalize_board_init(struct board_t *brd) {
                        DPR_INIT(("Requested and received usage of IRQ %d\n", brd->irq));
                }
        }
-       return(rc);
+       return rc;
 }
 
 /*
  * Remap PCI memory.
  */
-static void dgnc_do_remap(struct board_t *brd)
+static void dgnc_do_remap(struct dgnc_board *brd)
 {
 
        if (!brd || brd->magic != DGNC_BOARD_MAGIC)
@@ -802,7 +787,7 @@ static void dgnc_do_remap(struct board_t *brd)
 
 static void dgnc_poll_handler(ulong dummy)
 {
-       struct board_t *brd;
+       struct dgnc_board *brd;
        unsigned long lock_flags;
        int i;
        unsigned long new_time;
@@ -900,7 +885,7 @@ int dgnc_ms_sleep(ulong ms)
 {
        current->state = TASK_INTERRUPTIBLE;
        schedule_timeout((ms * HZ) / 1000);
-       return (signal_pending(current));
+       return signal_pending(current);
 }
 
 
@@ -912,47 +897,47 @@ char *dgnc_ioctl_name(int cmd)
 {
        switch(cmd) {
 
-       case TCGETA:            return("TCGETA");
-       case TCGETS:            return("TCGETS");
-       case TCSETA:            return("TCSETA");
-       case TCSETS:            return("TCSETS");
-       case TCSETAW:           return("TCSETAW");
-       case TCSETSW:           return("TCSETSW");
-       case TCSETAF:           return("TCSETAF");
-       case TCSETSF:           return("TCSETSF");
-       case TCSBRK:            return("TCSBRK");
-       case TCXONC:            return("TCXONC");
-       case TCFLSH:            return("TCFLSH");
-       case TIOCGSID:          return("TIOCGSID");
-
-       case TIOCGETD:          return("TIOCGETD");
-       case TIOCSETD:          return("TIOCSETD");
-       case TIOCGWINSZ:        return("TIOCGWINSZ");
-       case TIOCSWINSZ:        return("TIOCSWINSZ");
-
-       case TIOCMGET:          return("TIOCMGET");
-       case TIOCMSET:          return("TIOCMSET");
-       case TIOCMBIS:          return("TIOCMBIS");
-       case TIOCMBIC:          return("TIOCMBIC");
+       case TCGETA:            return "TCGETA";
+       case TCGETS:            return "TCGETS";
+       case TCSETA:            return "TCSETA";
+       case TCSETS:            return "TCSETS";
+       case TCSETAW:           return "TCSETAW";
+       case TCSETSW:           return "TCSETSW";
+       case TCSETAF:           return "TCSETAF";
+       case TCSETSF:           return "TCSETSF";
+       case TCSBRK:            return "TCSBRK";
+       case TCXONC:            return "TCXONC";
+       case TCFLSH:            return "TCFLSH";
+       case TIOCGSID:          return "TIOCGSID";
+
+       case TIOCGETD:          return "TIOCGETD";
+       case TIOCSETD:          return "TIOCSETD";
+       case TIOCGWINSZ:        return "TIOCGWINSZ";
+       case TIOCSWINSZ:        return "TIOCSWINSZ";
+
+       case TIOCMGET:          return "TIOCMGET";
+       case TIOCMSET:          return "TIOCMSET";
+       case TIOCMBIS:          return "TIOCMBIS";
+       case TIOCMBIC:          return "TIOCMBIC";
 
        /* from digi.h */
-       case DIGI_SETA:         return("DIGI_SETA");
-       case DIGI_SETAW:        return("DIGI_SETAW");
-       case DIGI_SETAF:        return("DIGI_SETAF");
-       case DIGI_SETFLOW:      return("DIGI_SETFLOW");
-       case DIGI_SETAFLOW:     return("DIGI_SETAFLOW");
-       case DIGI_GETFLOW:      return("DIGI_GETFLOW");
-       case DIGI_GETAFLOW:     return("DIGI_GETAFLOW");
-       case DIGI_GETA:         return("DIGI_GETA");
-       case DIGI_GEDELAY:      return("DIGI_GEDELAY");
-       case DIGI_SEDELAY:      return("DIGI_SEDELAY");
-       case DIGI_GETCUSTOMBAUD: return("DIGI_GETCUSTOMBAUD");
-       case DIGI_SETCUSTOMBAUD: return("DIGI_SETCUSTOMBAUD");
-       case TIOCMODG:          return("TIOCMODG");
-       case TIOCMODS:          return("TIOCMODS");
-       case TIOCSDTR:          return("TIOCSDTR");
-       case TIOCCDTR:          return("TIOCCDTR");
-
-       default:                return("unknown");
+       case DIGI_SETA:         return "DIGI_SETA";
+       case DIGI_SETAW:        return "DIGI_SETAW";
+       case DIGI_SETAF:        return "DIGI_SETAF";
+       case DIGI_SETFLOW:      return "DIGI_SETFLOW";
+       case DIGI_SETAFLOW:     return "DIGI_SETAFLOW";
+       case DIGI_GETFLOW:      return "DIGI_GETFLOW";
+       case DIGI_GETAFLOW:     return "DIGI_GETAFLOW";
+       case DIGI_GETA:         return "DIGI_GETA";
+       case DIGI_GEDELAY:      return "DIGI_GEDELAY";
+       case DIGI_SEDELAY:      return "DIGI_SEDELAY";
+       case DIGI_GETCUSTOMBAUD: return "DIGI_GETCUSTOMBAUD";
+       case DIGI_SETCUSTOMBAUD: return "DIGI_SETCUSTOMBAUD";
+       case TIOCMODG:          return "TIOCMODG";
+       case TIOCMODS:          return "TIOCMODS";
+       case TIOCSDTR:          return "TIOCSDTR";
+       case TIOCCDTR:          return "TIOCCDTR";
+
+       default:                return "unknown";
        }
 }
index 218b15dccb7dc970bef7bd1d56d491b51ad16884..3519b803e7535be17d22adc9e7f889859f9ff577 100644 (file)
@@ -45,7 +45,7 @@
 /*
  * Driver identification, error and debugging statments
  *
- * In theory, you can change all occurances of "digi" in the next
+ * In theory, you can change all occurrences of "digi" in the next
  * three lines, and the driver printk's will all automagically change.
  *
  * APR((fmt, args, ...));      Always prints message
@@ -246,7 +246,7 @@ enum {
  *
  *************************************************************************/
 
-struct board_t;
+struct dgnc_board;
 struct channel_t;
 
 /************************************************************************
@@ -259,7 +259,7 @@ struct board_ops {
        void (*uart_off) (struct channel_t *ch);
        int  (*drain) (struct tty_struct *tty, uint seconds);
        void (*param) (struct tty_struct *tty);
-       void (*vpd) (struct board_t *brd);
+       void (*vpd) (struct dgnc_board *brd);
        void (*assert_modem_signals) (struct channel_t *ch);
        void (*flush_uart_write) (struct channel_t *ch);
        void (*flush_uart_read) (struct channel_t *ch);
@@ -282,7 +282,7 @@ struct board_ops {
 /*
  *     Per-board information
  */
-struct board_t {
+struct dgnc_board {
        int             magic;          /* Board Magic number.  */
        int             boardnum;       /* Board number: 0-32 */
 
@@ -449,7 +449,7 @@ struct un_t {
  ************************************************************************/
 struct channel_t {
        int magic;                      /* Channel Magic Number         */
-       struct board_t  *ch_bd;         /* Board structure pointer      */
+       struct dgnc_board       *ch_bd;         /* Board structure pointer      */
        struct digi_t   ch_digi;        /* Transparent Print structure  */
        struct un_t     ch_tun;         /* Terminal unit info      */
        struct un_t     ch_pun;         /* Printer unit info        */
@@ -555,7 +555,7 @@ extern int          dgnc_poll_tick;         /* Poll interval - 20 ms        */
 extern int             dgnc_trcbuf_size;       /* Size of the ringbuffer       */
 extern spinlock_t      dgnc_global_lock;       /* Driver global spinlock       */
 extern uint            dgnc_NumBoards;         /* Total number of boards       */
-extern struct board_t  *dgnc_Board[MAXBOARDS]; /* Array of board structs       */
+extern struct dgnc_board       *dgnc_Board[MAXBOARDS]; /* Array of board structs       */
 extern ulong           dgnc_poll_counter;      /* Times the poller has run     */
 extern char            *dgnc_state_text[];     /* Array of state text          */
 extern char            *dgnc_driver_state_text[];/* Array of driver state text */
index 00f589a13ab9d4ad7dc0dd82a4f1ef04a406bcbf..eaec7e6a28e131eabaae19139496be79e8422ac1 100644 (file)
 #ifndef __DGNC_KCOMPAT_H
 #define __DGNC_KCOMPAT_H
 
-#include <linux/version.h>
-
-# ifndef KERNEL_VERSION
-#  define KERNEL_VERSION(a,b,c)  (((a) << 16) + ((b) << 8) + (c))
-# endif
-
-
 #if !defined(TTY_FLIPBUF_SIZE)
 # define TTY_FLIPBUF_SIZE 512
 #endif
                module_param(VAR, long, PERM); \
                MODULE_PARM_DESC(VAR, DESC);
 
-
-
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-
-
-
-/* NOTHING YET */
-
-
-
-# else
-
-
-
-# error "this driver does not support anything below the 2.6.27 kernel series."
-
-
-
-# endif
-
 #endif /* ! __DGNC_KCOMPAT_H */
index c4629d7c80b21bb72400e1074662438ce518192a..1c5ab3d007b00e126348cf0b3cace1b250b9a81f 100644 (file)
@@ -74,13 +74,13 @@ int dgnc_mgmt_open(struct inode *inode, struct file *file)
                /* Only allow 1 open at a time on mgmt device */
                if (dgnc_mgmt_in_use[minor]) {
                        DGNC_UNLOCK(dgnc_global_lock, lock_flags);
-                       return (-EBUSY);
+                       return -EBUSY;
                }
                dgnc_mgmt_in_use[minor]++;
        }
        else {
                DGNC_UNLOCK(dgnc_global_lock, lock_flags);
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        DGNC_UNLOCK(dgnc_global_lock, lock_flags);
@@ -154,7 +154,7 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        ddi.dinfo_nboards, ddi.dinfo_version));
 
                if (copy_to_user(uarg, &ddi, sizeof (ddi)))
-                       return(-EFAULT);
+                       return -EFAULT;
 
                break;
        }
@@ -166,13 +166,13 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                struct digi_info di;
 
                if (copy_from_user(&brd, uarg, sizeof(int))) {
-                       return(-EFAULT);
+                       return -EFAULT;
                }
 
                DPR_MGMT(("DIGI_GETBD asking about board: %d\n", brd));
 
                if ((brd < 0) || (brd > dgnc_NumBoards) || (dgnc_NumBoards == 0))
-                       return (-ENODEV);
+                       return -ENODEV;
 
                memset(&di, 0, sizeof(di));
 
@@ -196,7 +196,7 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                        di.info_bdtype, di.info_bdstate, di.info_nports, di.info_physsize));
 
                if (copy_to_user(uarg, &di, sizeof (di)))
-                       return (-EFAULT);
+                       return -EFAULT;
 
                break;
        }
@@ -209,8 +209,8 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                uint board = 0;
                uint channel = 0;
 
-               if (copy_from_user(&ni, uarg, sizeof(struct ni_info))) {
-                       return(-EFAULT);
+               if (copy_from_user(&ni, uarg, sizeof(ni))) {
+                       return -EFAULT;
                }
 
                DPR_MGMT(("DIGI_GETBD asking about board: %d channel: %d\n",
@@ -220,17 +220,17 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                channel = ni.channel;
 
                /* Verify boundaries on board */
-               if ((board < 0) || (board > dgnc_NumBoards) || (dgnc_NumBoards == 0))
-                       return (-ENODEV);
+               if ((board > dgnc_NumBoards) || (dgnc_NumBoards == 0))
+                       return -ENODEV;
 
                /* Verify boundaries on channel */
                if ((channel < 0) || (channel > dgnc_Board[board]->nasync))
-                       return (-ENODEV);
+                       return -ENODEV;
 
                ch = dgnc_Board[board]->channels[channel];
 
                if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-                       return (-ENODEV);
+                       return -ENODEV;
 
                memset(&ni, 0, sizeof(ni));
                ni.board = board;
@@ -291,7 +291,7 @@ long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
                if (copy_to_user(uarg, &ni, sizeof(ni)))
-                       return (-EFAULT);
+                       return -EFAULT;
 
                break;
        }
index 8b9e09a83f757efb410ac4159180b235923ae8ef..dc5a138d8d4ad6aefa947fe5c24ed3015ef04b44 100644 (file)
@@ -43,8 +43,8 @@
 #include "dgnc_tty.h"
 #include "dgnc_trace.h"
 
-static inline void neo_parse_lsr(struct board_t *brd, uint port);
-static inline void neo_parse_isr(struct board_t *brd, uint port);
+static inline void neo_parse_lsr(struct dgnc_board *brd, uint port);
+static inline void neo_parse_isr(struct dgnc_board *brd, uint port);
 static void neo_copy_data_from_uart_to_queue(struct channel_t *ch);
 static inline void neo_clear_break(struct channel_t *ch, int force);
 static inline void neo_set_cts_flow_control(struct channel_t *ch);
@@ -56,7 +56,7 @@ static inline void neo_set_no_input_flow_control(struct channel_t *ch);
 static inline void neo_set_new_start_stop_chars(struct channel_t *ch);
 static void neo_parse_modem(struct channel_t *ch, uchar signals);
 static void neo_tasklet(unsigned long data);
-static void neo_vpd(struct board_t *brd);
+static void neo_vpd(struct dgnc_board *brd);
 static void neo_uart_init(struct channel_t *ch);
 static void neo_uart_off(struct channel_t *ch);
 static int neo_drain(struct tty_struct *tty, uint seconds);
@@ -107,7 +107,7 @@ static uint dgnc_offset_table[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0
  * In this case, we are reading the DVID (Read-only Device Identification)
  * value of the Neo card.
  */
-static inline void neo_pci_posting_flush(struct board_t *bd)
+static inline void neo_pci_posting_flush(struct dgnc_board *bd)
 {
        readb(bd->re_map_membase + 0x8D);
 }
@@ -411,7 +411,7 @@ static inline void neo_clear_break(struct channel_t *ch, int force)
 /*
  * Parse the ISR register.
  */
-static inline void neo_parse_isr(struct board_t *brd, uint port)
+static inline void neo_parse_isr(struct dgnc_board *brd, uint port)
 {
        struct channel_t *ch;
        uchar isr;
@@ -538,7 +538,7 @@ static inline void neo_parse_isr(struct board_t *brd, uint port)
 }
 
 
-static inline void neo_parse_lsr(struct board_t *brd, uint port)
+static inline void neo_parse_lsr(struct dgnc_board *brd, uint port)
 {
        struct channel_t *ch;
        int linestatus;
@@ -650,7 +650,7 @@ static void neo_param(struct tty_struct *tty)
        uchar uart_ier = 0;
        uint baud = 9600;
        int quot = 0;
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t   *un;
 
@@ -911,7 +911,7 @@ static void neo_param(struct tty_struct *tty)
  */
 static void neo_tasklet(unsigned long data)
 {
-       struct board_t *bd = (struct board_t *) data;
+       struct dgnc_board *bd = (struct dgnc_board *) data;
        struct channel_t *ch;
        ulong  lock_flags;
        int i;
@@ -994,7 +994,7 @@ static void neo_tasklet(unsigned long data)
  */
 static irqreturn_t neo_intr(int irq, void *voidbrd)
 {
-       struct board_t *brd = (struct board_t *) voidbrd;
+       struct dgnc_board *brd = (struct dgnc_board *) voidbrd;
        struct channel_t *ch;
        int port = 0;
        int type = 0;
@@ -1111,7 +1111,7 @@ static irqreturn_t neo_intr(int irq, void *voidbrd)
                         * Why would I check EVERY possibility of type of
                         * interrupt, when we know its TXRDY???
                         * Becuz for some reason, even tho we got triggered for TXRDY,
-                        * it seems to be occassionally wrong. Instead of TX, which
+                        * it seems to be occasionally wrong. Instead of TX, which
                         * it should be, I was getting things like RXDY too. Weird.
                         */
                        neo_parse_isr(brd, port);
@@ -1404,17 +1404,17 @@ static int neo_drain(struct tty_struct *tty, uint seconds)
        int rc = 0;
 
        if (!tty || tty->magic != TTY_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        un = (struct un_t *) tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        DPR_IOCTL(("%d Drain wait started.\n", __LINE__));
@@ -1439,7 +1439,7 @@ static int neo_drain(struct tty_struct *tty, uint seconds)
                DPR_IOCTL(("%d Drain wait finished.\n", __LINE__));
        }
 
-       return (rc);
+       return rc;
 }
 
 
@@ -1939,7 +1939,7 @@ static unsigned int neo_read_eeprom(unsigned char __iomem *base, unsigned int ad
 }
 
 
-static void neo_vpd(struct board_t *brd)
+static void neo_vpd(struct dgnc_board *brd)
 {
        unsigned int i = 0;
        unsigned int a;
@@ -1965,7 +1965,7 @@ static void neo_vpd(struct board_t *brd)
        }
        else {
                /* Search for the serial number */
-               for (i = 0; i < NEO_VPD_IMAGESIZE * 2; i++) {
+               for (i = 0; i < NEO_VPD_IMAGEBYTES - 3; i++) {
                        if (brd->vpd[i] == 'S' && brd->vpd[i + 1] == 'N') {
                                strncpy(brd->serial_num, &(brd->vpd[i + 3]), 9);
                        }
index 7ec5710a4340f7ce54c462cb29df2d4929d925e3..1a4abb128693657bfc1fcfc7520f313fe18317b6 100644 (file)
@@ -47,7 +47,7 @@ struct neo_uart_struct {
        u8 fctr;                /* WR  FCTR - Feature Control Reg */
        u8 efr;         /* WR  EFR - Enhanced Function Reg */
        u8 tfifo;               /* WR  TXCNT/TXTRG - Transmit FIFO Reg */
-       u8 rfifo;               /* WR  RXCNT/RXTRG - Recieve  FIFO Reg */
+       u8 rfifo;               /* WR  RXCNT/RXTRG - Receive  FIFO Reg */
        u8 xoffchar1;   /* WR  XOFF 1 - XOff Character 1 Reg */
        u8 xoffchar2;   /* WR  XOFF 2 - XOff Character 2 Reg */
        u8 xonchar1;    /* WR  XON 1 - Xon Character 1 Reg */
index 0ea6c800280505639b2df05f554e7210f6888275..946230c234875009b07070a6ef22ca345552b74c 100644 (file)
@@ -152,19 +152,19 @@ void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver)
 
 #define DGNC_VERIFY_BOARD(p, bd)                       \
        if (!p)                                         \
-               return (0);                             \
+               return 0;                               \
                                                        \
        bd = dev_get_drvdata(p);                        \
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)       \
-               return (0);                             \
+               return 0;                               \
        if (bd->state != BOARD_READY)                   \
-               return (0);                             \
+               return 0;                               \
 
 
 
 static ssize_t dgnc_vpd_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -184,7 +184,7 @@ static DEVICE_ATTR(vpd, S_IRUSR, dgnc_vpd_show, NULL);
 
 static ssize_t dgnc_serial_number_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
 
        DGNC_VERIFY_BOARD(p, bd);
@@ -201,7 +201,7 @@ static DEVICE_ATTR(serial_number, S_IRUSR, dgnc_serial_number_show, NULL);
 
 static ssize_t dgnc_ports_state_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -219,7 +219,7 @@ static DEVICE_ATTR(ports_state, S_IRUSR, dgnc_ports_state_show, NULL);
 
 static ssize_t dgnc_ports_baud_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -236,7 +236,7 @@ static DEVICE_ATTR(ports_baud, S_IRUSR, dgnc_ports_baud_show, NULL);
 
 static ssize_t dgnc_ports_msignals_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -264,7 +264,7 @@ static DEVICE_ATTR(ports_msignals, S_IRUSR, dgnc_ports_msignals_show, NULL);
 
 static ssize_t dgnc_ports_iflag_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -281,7 +281,7 @@ static DEVICE_ATTR(ports_iflag, S_IRUSR, dgnc_ports_iflag_show, NULL);
 
 static ssize_t dgnc_ports_cflag_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -298,7 +298,7 @@ static DEVICE_ATTR(ports_cflag, S_IRUSR, dgnc_ports_cflag_show, NULL);
 
 static ssize_t dgnc_ports_oflag_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -315,7 +315,7 @@ static DEVICE_ATTR(ports_oflag, S_IRUSR, dgnc_ports_oflag_show, NULL);
 
 static ssize_t dgnc_ports_lflag_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -332,7 +332,7 @@ static DEVICE_ATTR(ports_lflag, S_IRUSR, dgnc_ports_lflag_show, NULL);
 
 static ssize_t dgnc_ports_digi_flag_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -349,7 +349,7 @@ static DEVICE_ATTR(ports_digi_flag, S_IRUSR, dgnc_ports_digi_flag_show, NULL);
 
 static ssize_t dgnc_ports_rxcount_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -366,7 +366,7 @@ static DEVICE_ATTR(ports_rxcount, S_IRUSR, dgnc_ports_rxcount_show, NULL);
 
 static ssize_t dgnc_ports_txcount_show(struct device *p, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        int count = 0;
        int i = 0;
 
@@ -384,7 +384,7 @@ static DEVICE_ATTR(ports_txcount, S_IRUSR, dgnc_ports_txcount_show, NULL);
 /* this function creates the sys files that will export each signal status
  * to sysfs each value will be put in a separate filename
  */
-void dgnc_create_ports_sysfiles(struct board_t *bd)
+void dgnc_create_ports_sysfiles(struct dgnc_board *bd)
 {
        int rc = 0;
 
@@ -408,7 +408,7 @@ void dgnc_create_ports_sysfiles(struct board_t *bd)
 
 
 /* removes all the sys files created for that port */
-void dgnc_remove_ports_sysfiles(struct board_t *bd)
+void dgnc_remove_ports_sysfiles(struct dgnc_board *bd)
 {
        device_remove_file(&(bd->pdev->dev), &dev_attr_ports_state);
        device_remove_file(&(bd->pdev->dev), &dev_attr_ports_baud);
@@ -427,23 +427,23 @@ void dgnc_remove_ports_sysfiles(struct board_t *bd)
 
 static ssize_t dgnc_tty_state_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%s", un->un_open_count ? "Open" : "Closed");
 }
@@ -452,23 +452,23 @@ static DEVICE_ATTR(state, S_IRUSR, dgnc_tty_state_show, NULL);
 
 static ssize_t dgnc_tty_baud_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_old_baud);
 }
@@ -477,23 +477,23 @@ static DEVICE_ATTR(baud, S_IRUSR, dgnc_tty_baud_show, NULL);
 
 static ssize_t dgnc_tty_msignals_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        if (ch->ch_open_count) {
                return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
@@ -511,23 +511,23 @@ static DEVICE_ATTR(msignals, S_IRUSR, dgnc_tty_msignals_show, NULL);
 
 static ssize_t dgnc_tty_iflag_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_iflag);
 }
@@ -536,23 +536,23 @@ static DEVICE_ATTR(iflag, S_IRUSR, dgnc_tty_iflag_show, NULL);
 
 static ssize_t dgnc_tty_cflag_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_cflag);
 }
@@ -561,23 +561,23 @@ static DEVICE_ATTR(cflag, S_IRUSR, dgnc_tty_cflag_show, NULL);
 
 static ssize_t dgnc_tty_oflag_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_oflag);
 }
@@ -586,23 +586,23 @@ static DEVICE_ATTR(oflag, S_IRUSR, dgnc_tty_oflag_show, NULL);
 
 static ssize_t dgnc_tty_lflag_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_c_lflag);
 }
@@ -611,23 +611,23 @@ static DEVICE_ATTR(lflag, S_IRUSR, dgnc_tty_lflag_show, NULL);
 
 static ssize_t dgnc_tty_digi_flag_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
 }
@@ -636,23 +636,23 @@ static DEVICE_ATTR(digi_flag, S_IRUSR, dgnc_tty_digi_flag_show, NULL);
 
 static ssize_t dgnc_tty_rxcount_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_rxcount);
 }
@@ -661,23 +661,23 @@ static DEVICE_ATTR(rxcount, S_IRUSR, dgnc_tty_rxcount_show, NULL);
 
 static ssize_t dgnc_tty_txcount_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%ld\n", ch->ch_txcount);
 }
@@ -686,23 +686,23 @@ static DEVICE_ATTR(txcount, S_IRUSR, dgnc_tty_txcount_show, NULL);
 
 static ssize_t dgnc_tty_name_show(struct device *d, struct device_attribute *attr, char *buf)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
 
        if (!d)
-               return (0);
-       un = (struct un_t *) dev_get_drvdata(d);
+               return 0;
+       un = dev_get_drvdata(d);
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (0);
+               return 0;
        if (bd->state != BOARD_READY)
-               return (0);
+               return 0;
 
        return snprintf(buf, PAGE_SIZE, "%sn%d%c\n",
                (un->un_type == DGNC_PRINT) ? "pr" : "tty",
index 4b87ce1cc7a2434c5b56124fabdba2751c1a0dd7..68c0de5898a483c6c918c7cd10d69932e56f7129 100644 (file)
 
 #include <linux/device.h>
 
-struct board_t;
+struct dgnc_board;
 struct channel_t;
 struct un_t;
 struct pci_driver;
 struct class_device;
 
-extern void dgnc_create_ports_sysfiles(struct board_t *bd);
-extern void dgnc_remove_ports_sysfiles(struct board_t *bd);
+extern void dgnc_create_ports_sysfiles(struct dgnc_board *bd);
+extern void dgnc_remove_ports_sysfiles(struct dgnc_board *bd);
 
 extern void dgnc_create_driver_sysfiles(struct pci_driver *);
 extern void dgnc_remove_driver_sysfiles(struct pci_driver *);
index a7bb6bceb9e7b738ee072c7040df97c72a0ec7d7..a6c6aba82d724d1f6a97029a39e83de385366337 100644 (file)
@@ -38,7 +38,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/sched.h>       /* For jiffies, task states */
 #include <linux/interrupt.h>   /* For tasklet and interrupt structs/defines */
 #include <linux/module.h>
 #include "dpacompat.h"
 #include "dgnc_sysfs.h"
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
 #define init_MUTEX(sem)         sema_init(sem, 1)
 #define DECLARE_MUTEX(name)     \
        struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)
-#endif
 
 /*
  * internal variables
  */
-static struct board_t  *dgnc_BoardsByMajor[256];
+static struct dgnc_board       *dgnc_BoardsByMajor[256];
 static uchar           *dgnc_TmpWriteBuf = NULL;
 static DECLARE_MUTEX(dgnc_TmpWriteSem);
 
@@ -126,13 +123,8 @@ static void dgnc_tty_flush_buffer(struct tty_struct *tty);
 static void dgnc_tty_hangup(struct tty_struct *tty);
 static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, unsigned int __user *value);
 static int dgnc_get_modem_info(struct channel_t *ch, unsigned int __user *value);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
 static int dgnc_tty_tiocmget(struct tty_struct *tty);
 static int dgnc_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear);
-#else
-static int dgnc_tty_tiocmget(struct tty_struct *tty, struct file *file);
-static int dgnc_tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
-#endif
 static int dgnc_tty_send_break(struct tty_struct *tty, int msec);
 static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout);
 static int dgnc_tty_write(struct tty_struct *tty, const unsigned char *buf, int count);
@@ -190,10 +182,10 @@ int dgnc_tty_preinit(void)
 
        if (!dgnc_TmpWriteBuf) {
                DPR_INIT(("unable to allocate tmp write buf"));
-               return (-ENOMEM);
+               return -ENOMEM;
        }
 
-       return(0);
+       return 0;
 }
 
 
@@ -202,14 +194,14 @@ int dgnc_tty_preinit(void)
  *
  * Init the tty subsystem for this board.
  */
-int dgnc_tty_register(struct board_t *brd)
+int dgnc_tty_register(struct dgnc_board *brd)
 {
        int rc = 0;
 
        DPR_INIT(("tty_register start\n"));
 
-       memset(&brd->SerialDriver, 0, sizeof(struct tty_driver));
-       memset(&brd->PrintDriver, 0, sizeof(struct tty_driver));
+       memset(&brd->SerialDriver, 0, sizeof(brd->SerialDriver));
+       memset(&brd->PrintDriver, 0, sizeof(brd->PrintDriver));
 
        brd->SerialDriver.magic = TTY_DRIVER_MAGIC;
 
@@ -230,25 +222,15 @@ int dgnc_tty_register(struct board_t *brd)
         * The kernel wants space to store pointers to
         * tty_struct's and termios's.
         */
-       brd->SerialDriver.ttys = kzalloc(brd->maxports * sizeof(struct tty_struct *), GFP_KERNEL);
+       brd->SerialDriver.ttys = kzalloc(brd->maxports * sizeof(*brd->SerialDriver.ttys), GFP_KERNEL);
        if (!brd->SerialDriver.ttys)
-               return(-ENOMEM);
+               return -ENOMEM;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
-       brd->SerialDriver.refcount = brd->TtyRefCnt;
-#else
        kref_init(&brd->SerialDriver.kref);
-#endif
-
-       brd->SerialDriver.termios = kzalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
+       brd->SerialDriver.termios = kzalloc(brd->maxports * sizeof(*brd->SerialDriver.termios), GFP_KERNEL);
        if (!brd->SerialDriver.termios)
-               return(-ENOMEM);
+               return -ENOMEM;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
-       brd->SerialDriver.termios_locked = kzalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
-       if (!brd->SerialDriver.termios_locked)
-               return(-ENOMEM);
-#endif
        /*
         * Entry points for driver.  Called by the kernel from
         * tty_io.c and n_tty.c.
@@ -260,14 +242,14 @@ int dgnc_tty_register(struct board_t *brd)
                rc = tty_register_driver(&brd->SerialDriver);
                if (rc < 0) {
                        APR(("Can't register tty device (%d)\n", rc));
-                       return(rc);
+                       return rc;
                }
                brd->dgnc_Major_Serial_Registered = TRUE;
        }
 
        /*
         * If we're doing transparent print, we have to do all of the above
-        * again, seperately so we don't get the LD confused about what major
+        * again, separately so we don't get the LD confused about what major
         * we are when we get into the dgnc_tty_open() routine.
         */
        brd->PrintDriver.magic = TTY_DRIVER_MAGIC;
@@ -286,28 +268,16 @@ int dgnc_tty_register(struct board_t *brd)
 
        /*
         * The kernel wants space to store pointers to
-        * tty_struct's and termios's.  Must be seperate from
+        * tty_struct's and termios's.  Must be separated from
         * the Serial Driver so we don't get confused
         */
-       brd->PrintDriver.ttys = kzalloc(brd->maxports * sizeof(struct tty_struct *), GFP_KERNEL);
+       brd->PrintDriver.ttys = kzalloc(brd->maxports * sizeof(*brd->PrintDriver.ttys), GFP_KERNEL);
        if (!brd->PrintDriver.ttys)
-               return(-ENOMEM);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
-       brd->PrintDriver.refcount = brd->TtyRefCnt;
-#else
+               return -ENOMEM;
        kref_init(&brd->PrintDriver.kref);
-#endif
-
-       brd->PrintDriver.termios = kzalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
+       brd->PrintDriver.termios = kzalloc(brd->maxports * sizeof(*brd->PrintDriver.termios), GFP_KERNEL);
        if (!brd->PrintDriver.termios)
-               return(-ENOMEM);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
-       brd->PrintDriver.termios_locked = kzalloc(brd->maxports * sizeof(struct ktermios *), GFP_KERNEL);
-       if (!brd->PrintDriver.termios_locked)
-               return(-ENOMEM);
-#endif
+               return -ENOMEM;
 
        /*
         * Entry points for driver.  Called by the kernel from
@@ -320,7 +290,7 @@ int dgnc_tty_register(struct board_t *brd)
                rc = tty_register_driver(&brd->PrintDriver);
                if (rc < 0) {
                        APR(("Can't register Transparent Print device (%d)\n", rc));
-                       return(rc);
+                       return rc;
                }
                brd->dgnc_Major_TransparentPrint_Registered = TRUE;
        }
@@ -331,7 +301,7 @@ int dgnc_tty_register(struct board_t *brd)
 
        DPR_INIT(("DGNC REGISTER TTY: MAJOR: %d\n", brd->SerialDriver.major));
 
-       return (rc);
+       return rc;
 }
 
 
@@ -341,14 +311,14 @@ int dgnc_tty_register(struct board_t *brd)
  * Init the tty subsystem.  Called once per board after board has been
  * downloaded and init'ed.
  */
-int dgnc_tty_init(struct board_t *brd)
+int dgnc_tty_init(struct dgnc_board *brd)
 {
        int i;
        void __iomem *vaddr;
        struct channel_t *ch;
 
        if (!brd)
-               return (-ENXIO);
+               return -ENXIO;
 
        DPR_INIT(("dgnc_tty_init start\n"));
 
@@ -371,7 +341,7 @@ int dgnc_tty_init(struct board_t *brd)
                         * Okay to malloc with GFP_KERNEL, we are not at
                         * interrupt context, and there are no locks held.
                         */
-                       brd->channels[i] = kzalloc(sizeof(struct channel_t), GFP_KERNEL);
+                       brd->channels[i] = kzalloc(sizeof(*brd->channels[i]), GFP_KERNEL);
                        if (!brd->channels[i]) {
                                DPR_CORE(("%s:%d Unable to allocate memory for channel struct\n",
                                    __FILE__, __LINE__));
@@ -436,7 +406,7 @@ int dgnc_tty_init(struct board_t *brd)
 
        DPR_INIT(("dgnc_tty_init finish\n"));
 
-       return (0);
+       return 0;
 }
 
 
@@ -460,7 +430,7 @@ void dgnc_tty_post_uninit(void)
  * Uninitialize the TTY portion of this driver.  Free all memory and
  * resources.
  */
-void dgnc_tty_uninit(struct board_t *brd)
+void dgnc_tty_uninit(struct dgnc_board *brd)
 {
        int i = 0;
 
@@ -550,7 +520,7 @@ void dgnc_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *buf, int
                /*
                 *  Loop while data remains.
                 */
-               while (nbuf > 0 && ch->ch_sniff_buf != 0) {
+               while (nbuf > 0 && ch->ch_sniff_buf) {
                        /*
                         *  Determine the amount of available space left in the
                         *  buffer.  If there's none, wait until some appears.
@@ -671,7 +641,7 @@ static void dgnc_wmove(struct channel_t *ch, char *buf, uint n)
  *=======================================================================*/
 void dgnc_input(struct channel_t *ch)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct tty_struct *tp;
        struct tty_ldisc *ld;
        uint    rmask;
@@ -867,7 +837,7 @@ void dgnc_input(struct channel_t *ch)
  ************************************************************************/
 void dgnc_carrier(struct channel_t *ch)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
 
        int virt_carrier = 0;
        int phys_carrier = 0;
@@ -1158,7 +1128,6 @@ void dgnc_wakeup_writes(struct channel_t *ch)
        }
 
        if (ch->ch_tun.un_flags & UN_ISOPEN) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
                if ((ch->ch_tun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
                        ch->ch_tun.un_tty->ldisc->ops->write_wakeup)
                {
@@ -1166,15 +1135,6 @@ void dgnc_wakeup_writes(struct channel_t *ch)
                        (ch->ch_tun.un_tty->ldisc->ops->write_wakeup)(ch->ch_tun.un_tty);
                        DGNC_LOCK(ch->ch_lock, lock_flags);
                }
-#else
-               if ((ch->ch_tun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                       ch->ch_tun.un_tty->ldisc.ops->write_wakeup)
-               {
-                       DGNC_UNLOCK(ch->ch_lock, lock_flags);
-                       (ch->ch_tun.un_tty->ldisc.ops->write_wakeup)(ch->ch_tun.un_tty);
-                       DGNC_LOCK(ch->ch_lock, lock_flags);
-               }
-#endif
 
                wake_up_interruptible(&ch->ch_tun.un_tty->write_wait);
 
@@ -1210,7 +1170,6 @@ void dgnc_wakeup_writes(struct channel_t *ch)
        }
 
        if (ch->ch_pun.un_flags & UN_ISOPEN) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
                if ((ch->ch_pun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
                        ch->ch_pun.un_tty->ldisc->ops->write_wakeup)
                {
@@ -1218,15 +1177,6 @@ void dgnc_wakeup_writes(struct channel_t *ch)
                        (ch->ch_pun.un_tty->ldisc->ops->write_wakeup)(ch->ch_pun.un_tty);
                        DGNC_LOCK(ch->ch_lock, lock_flags);
                }
-#else
-               if ((ch->ch_pun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                       ch->ch_pun.un_tty->ldisc.ops->write_wakeup)
-               {
-                       DGNC_UNLOCK(ch->ch_lock, lock_flags);
-                       (ch->ch_pun.un_tty->ldisc.ops->write_wakeup)(ch->ch_pun.un_tty);
-                       DGNC_LOCK(ch->ch_lock, lock_flags);
-               }
-#endif
 
                wake_up_interruptible(&ch->ch_pun.un_tty->write_wait);
 
@@ -1260,7 +1210,7 @@ void dgnc_wakeup_writes(struct channel_t *ch)
  */
 static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
 {
-       struct board_t  *brd;
+       struct dgnc_board       *brd;
        struct channel_t *ch;
        struct un_t     *un;
        uint            major = 0;
@@ -1473,7 +1423,7 @@ static int dgnc_tty_open(struct tty_struct *tty, struct file *file)
        DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
        DPR_OPEN(("dgnc_tty_open finished\n"));
-       return (rc);
+       return rc;
 }
 
 
@@ -1491,12 +1441,12 @@ static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file, struc
        int     sleep_on_un_flags = 0;
 
        if (!tty || tty->magic != TTY_MAGIC || !file || !ch || ch->magic != DGNC_CHANNEL_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC) {
-               return (-ENXIO);
+               return -ENXIO;
        }
 
        DPR_OPEN(("dgnc_block_til_ready - before block.\n"));
@@ -1624,12 +1574,12 @@ static int dgnc_block_til_ready(struct tty_struct *tty, struct file *file, struc
 
        if (retval) {
                DPR_OPEN(("dgnc_block_til_ready - done. error. retval: %x\n", retval));
-               return(retval);
+               return retval;
        }
 
        DPR_OPEN(("dgnc_block_til_ready - done no error. jiffies: %lu\n", jiffies));
 
-       return(0);
+       return 0;
 }
 
 
@@ -1667,7 +1617,7 @@ static void dgnc_tty_hangup(struct tty_struct *tty)
 static void dgnc_tty_close(struct tty_struct *tty, struct file *file)
 {
        struct ktermios *ts;
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        ulong lock_flags;
@@ -1843,15 +1793,15 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
        ulong   lock_flags = 0;
 
        if (tty == NULL)
-               return(0);
+               return 0;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
 
@@ -1873,7 +1823,7 @@ static int dgnc_tty_chars_in_buffer(struct tty_struct *tty)
        DPR_WRITE(("dgnc_tty_chars_in_buffer. Port: %x - %d (head: %d tail: %d)\n",
                ch->ch_portnum, chars, thead, ttail));
 
-       return(chars);
+       return chars;
 }
 
 
@@ -1891,22 +1841,22 @@ static int dgnc_maxcps_room(struct tty_struct *tty, int bytes_available)
        struct un_t *un = NULL;
 
        if (!tty)
-               return (bytes_available);
+               return bytes_available;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (bytes_available);
+               return bytes_available;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (bytes_available);
+               return bytes_available;
 
        /*
         * If its not the Transparent print device, return
         * the full data amount.
         */
        if (un->un_type != DGNC_PRINT)
-               return (bytes_available);
+               return bytes_available;
 
        if (ch->ch_digi.digi_maxcps > 0 && ch->ch_digi.digi_bufsize > 0 ) {
                int cps_limit = 0;
@@ -1931,7 +1881,7 @@ static int dgnc_maxcps_room(struct tty_struct *tty, int bytes_available)
                bytes_available = min(cps_limit, bytes_available);
        }
 
-       return (bytes_available);
+       return bytes_available;
 }
 
 
@@ -1951,15 +1901,15 @@ static int dgnc_tty_write_room(struct tty_struct *tty)
        ulong   lock_flags = 0;
 
        if (tty == NULL || dgnc_TmpWriteBuf == NULL)
-               return(0);
+               return 0;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (0);
+               return 0;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (0);
+               return 0;
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
 
@@ -1994,7 +1944,7 @@ static int dgnc_tty_write_room(struct tty_struct *tty)
 
        DPR_WRITE(("dgnc_tty_write_room - %d tail: %d head: %d\n", ret, tail, head));
 
-       return(ret);
+       return ret;
 }
 
 
@@ -2037,18 +1987,18 @@ static int dgnc_tty_write(struct tty_struct *tty,
        int from_user = 0;
 
        if (tty == NULL || dgnc_TmpWriteBuf == NULL)
-               return(0);
+               return 0;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return(0);
+               return 0;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return(0);
+               return 0;
 
        if (!count)
-               return(0);
+               return 0;
 
        DPR_WRITE(("dgnc_tty_write: Port: %x tty=%p user=%d len=%d\n",
                ch->ch_portnum, tty, from_user, count));
@@ -2090,7 +2040,7 @@ static int dgnc_tty_write(struct tty_struct *tty,
         */
        if (count <= 0) {
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(0);
+               return 0;
        }
 
        /*
@@ -2120,7 +2070,7 @@ static int dgnc_tty_write(struct tty_struct *tty,
         */
        if (count <= 0) {
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(0);
+               return 0;
        }
 
        if (from_user) {
@@ -2136,7 +2086,7 @@ static int dgnc_tty_write(struct tty_struct *tty,
                 */
                /* we're allowed to block if it's from_user */
                if (down_interruptible(&dgnc_TmpWriteSem)) {
-                       return (-EINTR);
+                       return -EINTR;
                }
 
                /*
@@ -2147,7 +2097,7 @@ static int dgnc_tty_write(struct tty_struct *tty,
 
                if (!count) {
                        up(&dgnc_TmpWriteSem);
-                       return(-EFAULT);
+                       return -EFAULT;
                }
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -2229,18 +2179,15 @@ static int dgnc_tty_write(struct tty_struct *tty,
                ch->ch_bd->bd_ops->copy_data_from_queue_to_uart(ch);
        }
 
-       return (count);
+       return count;
 }
 
 
 /*
  * Return modem signals to ld.
  */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
+
 static int dgnc_tty_tiocmget(struct tty_struct *tty)
-#else
-static int dgnc_tty_tiocmget(struct tty_struct *tty, struct file *file)
-#endif
 {
        struct channel_t *ch;
        struct un_t *un;
@@ -2293,15 +2240,11 @@ static int dgnc_tty_tiocmget(struct tty_struct *tty, struct file *file)
  *
  * Set modem signals, called by ld.
  */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
+
 static int dgnc_tty_tiocmset(struct tty_struct *tty,
                unsigned int set, unsigned int clear)
-#else
-static int dgnc_tty_tiocmset(struct tty_struct *tty, struct file *file,
-               unsigned int set, unsigned int clear)
-#endif
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        int ret = -EIO;
@@ -2349,7 +2292,7 @@ static int dgnc_tty_tiocmset(struct tty_struct *tty, struct file *file,
 
        DPR_IOCTL(("dgnc_tty_tiocmset finish\n"));
 
-       return (0);
+       return 0;
 }
 
 
@@ -2360,7 +2303,7 @@ static int dgnc_tty_tiocmset(struct tty_struct *tty, struct file *file,
  */
 static int dgnc_tty_send_break(struct tty_struct *tty, int msec)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        int ret = -EIO;
@@ -2402,7 +2345,7 @@ static int dgnc_tty_send_break(struct tty_struct *tty, int msec)
 
        DPR_IOCTL(("dgnc_tty_send_break finish\n"));
 
-       return (0);
+       return 0;
 
 }
 
@@ -2414,7 +2357,7 @@ static int dgnc_tty_send_break(struct tty_struct *tty, int msec)
  */
 static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        int rc;
@@ -2450,7 +2393,7 @@ static void dgnc_tty_wait_until_sent(struct tty_struct *tty, int timeout)
  */
 static void dgnc_tty_send_xchar(struct tty_struct *tty, char c)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        ulong   lock_flags;
@@ -2497,7 +2440,7 @@ static inline int dgnc_get_mstat(struct channel_t *ch)
        DPR_IOCTL(("dgnc_getmstat start\n"));
 
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return(-ENXIO);
+               return -ENXIO;
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
 
@@ -2522,7 +2465,7 @@ static inline int dgnc_get_mstat(struct channel_t *ch)
 
        DPR_IOCTL(("dgnc_getmstat finish\n"));
 
-       return(result);
+       return result;
 }
 
 
@@ -2538,17 +2481,17 @@ static int dgnc_get_modem_info(struct channel_t *ch, unsigned int  __user *value
        DPR_IOCTL(("dgnc_get_modem_info start\n"));
 
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return(-ENXIO);
+               return -ENXIO;
 
        result = dgnc_get_mstat(ch);
 
        if (result < 0)
-               return (-ENXIO);
+               return -ENXIO;
 
        rc = put_user(result, value);
 
        DPR_IOCTL(("dgnc_get_modem_info finish\n"));
-       return(rc);
+       return rc;
 }
 
 
@@ -2559,7 +2502,7 @@ static int dgnc_get_modem_info(struct channel_t *ch, unsigned int  __user *value
  */
 static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, unsigned int __user *value)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        int ret = -ENXIO;
@@ -2587,7 +2530,7 @@ static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, uns
 
        ret = get_user(arg, value);
        if (ret)
-               return(ret);
+               return ret;
 
        switch (command) {
        case TIOCMBIS:
@@ -2631,7 +2574,7 @@ static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, uns
                break;
 
        default:
-               return(-EINVAL);
+               return -EINVAL;
        }
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -2642,7 +2585,7 @@ static int dgnc_set_modem_info(struct tty_struct *tty, unsigned int command, uns
 
        DPR_IOCTL(("dgnc_set_modem_info finish\n"));
 
-       return (0);
+       return 0;
 }
 
 
@@ -2662,18 +2605,18 @@ static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retin
        ulong   lock_flags;
 
        if (!retinfo)
-               return (-EFAULT);
+               return -EFAULT;
 
        if (!tty || tty->magic != TTY_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        memset(&tmp, 0, sizeof(tmp));
 
@@ -2682,9 +2625,9 @@ static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retin
        DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
        if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
-               return (-EFAULT);
+               return -EFAULT;
 
-       return (0);
+       return 0;
 }
 
 
@@ -2698,7 +2641,7 @@ static int dgnc_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retin
  */
 static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_info)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        struct digi_t new_digi;
@@ -2707,23 +2650,23 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i
        DPR_IOCTL(("DIGI_SETA start\n"));
 
        if (!tty || tty->magic != TTY_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (-EFAULT);
+               return -EFAULT;
 
-       if (copy_from_user(&new_digi, new_info, sizeof(struct digi_t))) {
+       if (copy_from_user(&new_digi, new_info, sizeof(new_digi))) {
                DPR_IOCTL(("DIGI_SETA failed copy_from_user\n"));
-               return(-EFAULT);
+               return -EFAULT;
        }
 
        DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -2744,7 +2687,7 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i
        if ((ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) && !(new_digi.digi_flags & DIGI_DTR_TOGGLE))
                ch->ch_mostat |= (UART_MCR_DTR);
 
-       memcpy(&ch->ch_digi, &new_digi, sizeof(struct digi_t));
+       memcpy(&ch->ch_digi, &new_digi, sizeof(new_digi));
 
        if (ch->ch_digi.digi_maxcps < 1)
                ch->ch_digi.digi_maxcps = 1;
@@ -2773,7 +2716,7 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i
 
        DPR_IOCTL(("DIGI_SETA finish\n"));
 
-       return(0);
+       return 0;
 }
 
 
@@ -2782,7 +2725,7 @@ static int dgnc_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i
  */
 static void dgnc_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        unsigned long lock_flags;
@@ -2878,7 +2821,7 @@ static void dgnc_tty_unthrottle(struct tty_struct *tty)
 
 static void dgnc_tty_start(struct tty_struct *tty)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        ulong lock_flags;
@@ -2912,7 +2855,7 @@ static void dgnc_tty_start(struct tty_struct *tty)
 
 static void dgnc_tty_stop(struct tty_struct *tty)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        ulong lock_flags;
@@ -2959,7 +2902,7 @@ static void dgnc_tty_stop(struct tty_struct *tty)
  */
 static void dgnc_tty_flush_chars(struct tty_struct *tty)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        ulong lock_flags;
@@ -3056,7 +2999,7 @@ static void dgnc_tty_flush_buffer(struct tty_struct *tty)
 static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                unsigned long arg)
 {
-       struct board_t *bd;
+       struct dgnc_board *bd;
        struct channel_t *ch;
        struct un_t *un;
        int rc;
@@ -3064,19 +3007,19 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
        void __user *uarg = (void __user *) arg;
 
        if (!tty || tty->magic != TTY_MAGIC)
-               return (-ENODEV);
+               return -ENODEV;
 
        un = tty->driver_data;
        if (!un || un->magic != DGNC_UNIT_MAGIC)
-               return (-ENODEV);
+               return -ENODEV;
 
        ch = un->un_ch;
        if (!ch || ch->magic != DGNC_CHANNEL_MAGIC)
-               return (-ENODEV);
+               return -ENODEV;
 
        bd = ch->ch_bd;
        if (!bd || bd->magic != DGNC_BOARD_MAGIC)
-               return (-ENODEV);
+               return -ENODEV;
 
        DPR_IOCTL(("dgnc_tty_ioctl start on port %d - cmd %s (%x), arg %lx\n",
                ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
@@ -3086,7 +3029,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
        if (un->un_open_count <= 0) {
                DPR_BASIC(("dgnc_tty_ioctl - unit not open.\n"));
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(-EIO);
+               return -EIO;
        }
 
        switch (cmd) {
@@ -3105,14 +3048,14 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                rc = tty_check_change(tty);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                if (rc) {
-                       return(rc);
+                       return rc;
                }
 
                rc = ch->ch_bd->bd_ops->drain(tty, 0);
 
                if (rc) {
                        DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
-                       return(-EINTR);
+                       return -EINTR;
                }
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -3126,7 +3069,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
                        ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
 
-               return(0);
+               return 0;
 
 
        case TCSBRKP:
@@ -3138,13 +3081,13 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                rc = tty_check_change(tty);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                if (rc) {
-                       return(rc);
+                       return rc;
                }
 
                rc = ch->ch_bd->bd_ops->drain(tty, 0);
                if (rc) {
                        DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
-                       return(-EINTR);
+                       return -EINTR;
                }
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -3156,19 +3099,19 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
                        ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
 
-               return(0);
+               return 0;
 
        case TIOCSBRK:
                rc = tty_check_change(tty);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                if (rc) {
-                       return(rc);
+                       return rc;
                }
 
                rc = ch->ch_bd->bd_ops->drain(tty, 0);
                if (rc) {
                        DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
-                       return(-EINTR);
+                       return -EINTR;
                }
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -3180,7 +3123,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
                        ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
 
-               return(0);
+               return 0;
 
        case TIOCCBRK:
                /* Do Nothing */
@@ -3192,31 +3135,31 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
                rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) arg);
-               return(rc);
+               return rc;
 
        case TIOCSSOFTCAR:
 
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                rc = get_user(arg, (unsigned long __user *) arg);
                if (rc)
-                       return(rc);
+                       return rc;
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
                tty->termios.c_cflag = ((tty->termios.c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
                ch->ch_bd->bd_ops->param(tty);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
-               return(0);
+               return 0;
 
        case TIOCMGET:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(dgnc_get_modem_info(ch, uarg));
+               return dgnc_get_modem_info(ch, uarg);
 
        case TIOCMBIS:
        case TIOCMBIC:
        case TIOCMSET:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(dgnc_set_modem_info(tty, cmd, uarg));
+               return dgnc_set_modem_info(tty, cmd, uarg);
 
                /*
                 * Here are any additional ioctl's that we want to implement
@@ -3235,7 +3178,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                rc = tty_check_change(tty);
                if (rc) {
                        DGNC_UNLOCK(ch->ch_lock, lock_flags);
-                       return(rc);
+                       return rc;
                }
 
                if ((arg == TCIFLUSH) || (arg == TCIOFLUSH)) {
@@ -3265,7 +3208,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                /* pretend we didn't recognize this IOCTL */
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(-ENOIOCTLCMD);
+               return -ENOIOCTLCMD;
        case TCSETSF:
        case TCSETSW:
                /*
@@ -3291,14 +3234,14 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                rc = ch->ch_bd->bd_ops->drain(tty, 0);
                if (rc) {
                        DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d\n", rc));
-                       return(-EINTR);
+                       return -EINTR;
                }
 
                DPR_IOCTL(("dgnc_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n",
                        ch->ch_portnum, dgnc_ioctl_name(cmd), cmd, arg));
 
                /* pretend we didn't recognize this */
-               return(-ENOIOCTLCMD);
+               return -ENOIOCTLCMD;
 
        case TCSETAW:
 
@@ -3306,21 +3249,21 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                rc = ch->ch_bd->bd_ops->drain(tty, 0);
                if (rc) {
                        DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
-                       return(-EINTR);
+                       return -EINTR;
                }
 
                /* pretend we didn't recognize this */
-               return(-ENOIOCTLCMD);
+               return -ENOIOCTLCMD;
 
        case TCXONC:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                /* Make the ld do it */
-               return(-ENOIOCTLCMD);
+               return -ENOIOCTLCMD;
 
        case DIGI_GETA:
                /* get information for ditty */
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(dgnc_tty_digigeta(tty, uarg));
+               return dgnc_tty_digigeta(tty, uarg);
 
        case DIGI_SETAW:
        case DIGI_SETAF:
@@ -3332,7 +3275,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                        rc = ch->ch_bd->bd_ops->drain(tty, 0);
                        if (rc) {
                                DPR_IOCTL(("dgnc_tty_ioctl - bad return: %d ", rc));
-                               return(-EINTR);
+                               return -EINTR;
                        }
                        DGNC_LOCK(ch->ch_lock, lock_flags);
                }
@@ -3343,7 +3286,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
        case DIGI_SETA:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(dgnc_tty_digiseta(tty, uarg));
+               return dgnc_tty_digiseta(tty, uarg);
 
        case DIGI_LOOPBACK:
                {
@@ -3352,7 +3295,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                        DGNC_UNLOCK(ch->ch_lock, lock_flags);
                        rc = get_user(loopback, (unsigned int __user *) arg);
                        if (rc)
-                               return(rc);
+                               return rc;
                        DGNC_LOCK(ch->ch_lock, lock_flags);
 
                        /* Enable/disable internal loopback for this port */
@@ -3363,13 +3306,13 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                        ch->ch_bd->bd_ops->param(tty);
                        DGNC_UNLOCK(ch->ch_lock, lock_flags);
-                       return(0);
+                       return 0;
                }
 
        case DIGI_GETCUSTOMBAUD:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                rc = put_user(ch->ch_custom_speed, (unsigned int __user *) arg);
-               return(rc);
+               return rc;
 
        case DIGI_SETCUSTOMBAUD:
        {
@@ -3378,12 +3321,12 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                rc = get_user(new_rate, (unsigned int __user *) arg);
                if (rc)
-                       return(rc);
+                       return rc;
                DGNC_LOCK(ch->ch_lock, lock_flags);
                dgnc_set_custom_speed(ch, new_rate);
                ch->ch_bd->bd_ops->param(tty);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(0);
+               return 0;
        }
 
        /*
@@ -3399,11 +3342,11 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                rc = get_user(c, (unsigned char __user *) arg);
                if (rc)
-                       return(rc);
+                       return rc;
                DGNC_LOCK(ch->ch_lock, lock_flags);
                ch->ch_bd->bd_ops->send_immediate_char(ch, c);
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
-               return(0);
+               return 0;
        }
 
        /*
@@ -3426,10 +3369,10 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
-               if (copy_to_user(uarg, &buf, sizeof(struct digi_getcounter))) {
-                       return (-EFAULT);
+               if (copy_to_user(uarg, &buf, sizeof(buf))) {
+                       return -EFAULT;
                }
-               return(0);
+               return 0;
        }
 
        /*
@@ -3454,7 +3397,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
                rc = put_user(events, (unsigned int __user *) arg);
-               return(rc);
+               return rc;
        }
 
        /*
@@ -3474,8 +3417,8 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                /*
                 * Get data from user first.
                 */
-               if (copy_from_user(&buf, uarg, sizeof(struct digi_getbuffer))) {
-                       return (-EFAULT);
+               if (copy_from_user(&buf, uarg, sizeof(buf))) {
+                       return -EFAULT;
                }
 
                DGNC_LOCK(ch->ch_lock, lock_flags);
@@ -3520,10 +3463,10 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
 
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
 
-               if (copy_to_user(uarg, &buf, sizeof(struct digi_getbuffer))) {
-                       return (-EFAULT);
+               if (copy_to_user(uarg, &buf, sizeof(buf))) {
+                       return -EFAULT;
                }
-               return(0);
+               return 0;
        }
        default:
                DGNC_UNLOCK(ch->ch_lock, lock_flags);
@@ -3532,7 +3475,7 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
                DPR_IOCTL(("dgnc_tty_ioctl end - cmd %s (%x), arg %lx\n",
                        dgnc_ioctl_name(cmd), cmd, arg));
 
-               return(-ENOIOCTLCMD);
+               return -ENOIOCTLCMD;
        }
 
        DGNC_UNLOCK(ch->ch_lock, lock_flags);
@@ -3540,5 +3483,5 @@ static int dgnc_tty_ioctl(struct tty_struct *tty, unsigned int cmd,
        DPR_IOCTL(("dgnc_tty_ioctl end - cmd %s (%x), arg %lx\n",
                dgnc_ioctl_name(cmd), cmd, arg));
 
-       return(0);
+       return 0;
 }
index deb388d2f4cff0861dbad385c35f3d6ce27dc1e2..9d1c2847bd9429617a7a10ff16538c03daf45435 100644 (file)
 
 #include "dgnc_driver.h"
 
-int    dgnc_tty_register(struct board_t *brd);
+int    dgnc_tty_register(struct dgnc_board *brd);
 
 int    dgnc_tty_preinit(void);
-int     dgnc_tty_init(struct board_t *);
+int     dgnc_tty_init(struct dgnc_board *);
 
 void   dgnc_tty_post_uninit(void);
-void   dgnc_tty_uninit(struct board_t *);
+void   dgnc_tty_uninit(struct dgnc_board *);
 
 void   dgnc_input(struct channel_t *ch);
 void   dgnc_carrier(struct channel_t *ch);
index eb6e3712572763c77987e45baed1a06b1c084bf1..6a9adf6591ebcaabf480c1e63d222d2d03ea807d 100644 (file)
@@ -201,9 +201,9 @@ struct shrink_buf_struct {
        unsigned int    shrink_buf_vaddr;       /* Virtual address of board */
        unsigned int    shrink_buf_phys;        /* Physical address of board */
        unsigned int    shrink_buf_bseg;        /* Amount of board memory */
-       unsigned int    shrink_buf_hseg;        /* '186 Begining of Dual-Port */
+       unsigned int    shrink_buf_hseg;        /* '186 Beginning of Dual-Port */
 
-       unsigned int    shrink_buf_lseg;        /* '186 Begining of freed memory */
+       unsigned int    shrink_buf_lseg;        /* '186 Beginning of freed memory */
        unsigned int    shrink_buf_mseg;        /* Linear address from start of
                                                   dual-port were freed memory
                                                   begins, host viewpoint. */
index 8cee9c8bc38b1850b8bdcc3edad37e91a6996515..9a18a2c9e73b20932ecb72d7fd6469617580c7c8 100644 (file)
@@ -157,7 +157,7 @@ static ssize_t dgrp_node_state_show(struct device *c,
 
        if (!c)
                return 0;
-       nd = (struct nd_struct *) dev_get_drvdata(c);
+       nd = dev_get_drvdata(c);
        if (!nd)
                return 0;
 
@@ -174,7 +174,7 @@ static ssize_t dgrp_node_description_show(struct device *c,
 
        if (!c)
                return 0;
-       nd = (struct nd_struct *) dev_get_drvdata(c);
+       nd = dev_get_drvdata(c);
        if (!nd)
                return 0;
 
@@ -192,7 +192,7 @@ static ssize_t dgrp_node_hw_version_show(struct device *c,
 
        if (!c)
                return 0;
-       nd = (struct nd_struct *) dev_get_drvdata(c);
+       nd = dev_get_drvdata(c);
        if (!nd)
                return 0;
 
@@ -212,7 +212,7 @@ static ssize_t dgrp_node_hw_id_show(struct device *c,
 
        if (!c)
                return 0;
-       nd = (struct nd_struct *) dev_get_drvdata(c);
+       nd = dev_get_drvdata(c);
        if (!nd)
                return 0;
 
@@ -232,7 +232,7 @@ static ssize_t dgrp_node_sw_version_show(struct device *c,
        if (!c)
                return 0;
 
-       nd = (struct nd_struct *) dev_get_drvdata(c);
+       nd = dev_get_drvdata(c);
        if (!nd)
                return 0;
 
@@ -311,7 +311,7 @@ static ssize_t dgrp_tty_state_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
 
@@ -328,7 +328,7 @@ static ssize_t dgrp_tty_baud_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -348,7 +348,7 @@ static ssize_t dgrp_tty_msignals_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -377,7 +377,7 @@ static ssize_t dgrp_tty_iflag_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -396,7 +396,7 @@ static ssize_t dgrp_tty_cflag_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -415,7 +415,7 @@ static ssize_t dgrp_tty_oflag_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -434,7 +434,7 @@ static ssize_t dgrp_tty_digi_flag_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -453,7 +453,7 @@ static ssize_t dgrp_tty_rxcount_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -472,7 +472,7 @@ static ssize_t dgrp_tty_txcount_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
@@ -493,7 +493,7 @@ static ssize_t dgrp_tty_name_show(struct device *d,
 
        if (!d)
                return 0;
-       un = (struct un_struct *) dev_get_drvdata(d);
+       un = dev_get_drvdata(d);
        if (!un)
                return 0;
        ch = un->un_ch;
diff --git a/drivers/staging/dwc2/TODO b/drivers/staging/dwc2/TODO
new file mode 100644 (file)
index 0000000..282470d
--- /dev/null
@@ -0,0 +1,33 @@
+TODO:
+       - Dan Carpenter would like to see some cleanups to the microframe
+         scheduler code:
+         http://www.mail-archive.com/linux-usb@vger.kernel.org/msg26650.html
+
+       - Should merge the NAK holdoff patch from Raspberry Pi
+         (http://marc.info/?l=linux-usb&m=137625067103833). But as it stands
+         that patch is incomplete, it needs more investigation to see if it
+         can be made to work for non-Raspberry Pi platforms that lack the
+         special FIQ interrupt that the Pi has. Without this patch, the driver
+         has a high interrupt rate (8K/sec).
+
+       - The Raspberry Pi platform needs to have support for its FIQ interrupt
+         added, to get the same level of functionality as the downstream
+         driver. The raspberrypi.org developers have indicated they are
+         willing to help with that.
+
+       - Some of the default driver parameters (see 'struct dwc2_core_params'
+         in core.h) won't work for many platforms. So DT attributes will need
+         to be added for some of these. But that can be done as-needed as new
+         platforms are added.
+
+       - Eventually the driver should be merged with the s3c-hsotg peripheral
+         mode driver, so that both modes of operation can be supported with a
+         single driver. But I think that can wait till after the driver has
+         been moved to mainline.
+
+       - After that, OTG support can be added. I'm not sure how much demand
+         there is for that, though, so I have that as a low priority.
+
+Please send any patches for this driver to Paul Zimmerman <paulz@synopsys.com>
+and Greg Kroah-Hartman <gregkh@linuxfoundation.org>. And please CC linux-usb
+<linux-usb@vger.kernel.org> too.
index 06dae67a9d6294499ebf5926a7734bd56e1dc1ec..6d001b52f6524a564360658eee2b37c55ddaf8a6 100644 (file)
@@ -564,7 +564,7 @@ void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 
        /*
         * This bit allows dynamic reloading of the HFIR register during
-        * runtime. This bit needs to be programmed during inital configuration
+        * runtime. This bit needs to be programmed during initial configuration
         * and its value must not be changed during runtime.
         */
        if (hsotg->core_params->reload_ctl > 0) {
@@ -2205,7 +2205,7 @@ int dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg, int val)
 {
 #ifndef NO_FS_PHY_HW_CHECKS
        int valid = 0;
-        u32 hs_phy_type, fs_phy_type;
+       u32 hs_phy_type, fs_phy_type;
 #endif
        int retval = 0;
 
@@ -2553,7 +2553,7 @@ int dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val)
                hsotg->core_params->ahbcfg = val;
        else
                hsotg->core_params->ahbcfg = GAHBCFG_HBSTLEN_INCR4 <<
-                                             GAHBCFG_HBSTLEN_SHIFT;
+                                               GAHBCFG_HBSTLEN_SHIFT;
        return 0;
 }
 
@@ -2736,6 +2736,26 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
        return 0;
 }
 
+int dwc2_set_param_uframe_sched(struct dwc2_hsotg *hsotg, int val)
+{
+       int retval = 0;
+
+       if (DWC2_PARAM_TEST(val, 0, 1)) {
+               if (val >= 0) {
+                       dev_err(hsotg->dev,
+                               "'%d' invalid for parameter uframe_sched\n",
+                               val);
+                       dev_err(hsotg->dev, "uframe_sched must be 0 or 1\n");
+               }
+               val = 1;
+               dev_dbg(hsotg->dev, "Setting uframe_sched to %d\n", val);
+               retval = -EINVAL;
+       }
+
+       hsotg->core_params->uframe_sched = val;
+       return retval;
+}
+
 /*
  * This function is called during module intialization to pass module parameters
  * for the DWC_otg core. It returns non-0 if any parameters are invalid.
@@ -2782,6 +2802,7 @@ int dwc2_set_parameters(struct dwc2_hsotg *hsotg,
        retval |= dwc2_set_param_reload_ctl(hsotg, params->reload_ctl);
        retval |= dwc2_set_param_ahbcfg(hsotg, params->ahbcfg);
        retval |= dwc2_set_param_otg_ver(hsotg, params->otg_ver);
+       retval |= dwc2_set_param_uframe_sched(hsotg, params->uframe_sched);
 
        return retval;
 }
index 9102f66d0111e8676ebd5be2ce1bc00dbdc4c8c5..fab718d9b326344860ed6af876a9a2e840893bb1 100644 (file)
@@ -188,6 +188,7 @@ enum dwc2_lx_state {
  *                      bits defined by GAHBCFG_CTRL_MASK are controlled
  *                      by the driver and are ignored in this
  *                      configuration value.
+ * @uframe_sched:       True to enable the microframe scheduler
  *
  * The following parameters may be specified when starting the module. These
  * parameters define how the DWC_otg controller should be configured. A
@@ -224,6 +225,7 @@ struct dwc2_core_params {
        int ts_dline;
        int reload_ctl;
        int ahbcfg;
+       int uframe_sched;
 };
 
 /**
@@ -292,7 +294,7 @@ struct dwc2_hw_params {
        unsigned dev_token_q_depth:5;
        unsigned max_transfer_size:26;
        unsigned max_packet_count:11;
-       unsigned host_channels:4;
+       unsigned host_channels:5;
        unsigned hs_phy_type:2;
        unsigned fs_phy_type:2;
        unsigned i2c_enable:1;
@@ -370,6 +372,7 @@ struct dwc2_hw_params {
  *                      This value is in microseconds per (micro)frame. The
  *                      assumption is that all periodic transfers may occur in
  *                      the same (micro)frame.
+ * @frame_usecs:        Internal variable used by the microframe scheduler
  * @frame_number:       Frame number read from the core at SOF. The value ranges
  *                      from 0 to HFNUM_MAX_FRNUM.
  * @periodic_qh_count:  Count of periodic QHs, if using several eps. Used for
@@ -382,6 +385,8 @@ struct dwc2_hw_params {
  *                      host channel is available for non-periodic transactions.
  * @non_periodic_channels: Number of host channels assigned to non-periodic
  *                      transfers
+ * @available_host_channels Number of host channels available for the microframe
+ *                      scheduler to use
  * @hc_ptr_array:       Array of pointers to the host channel descriptors.
  *                      Allows accessing a host channel descriptor given the
  *                      host channel number. This is useful in interrupt
@@ -436,6 +441,7 @@ struct dwc2_hsotg {
        struct list_head periodic_sched_assigned;
        struct list_head periodic_sched_queued;
        u16 periodic_usecs;
+       u16 frame_usecs[8];
        u16 frame_number;
        u16 periodic_qh_count;
 
@@ -451,6 +457,7 @@ struct dwc2_hsotg {
        struct list_head free_hc_list;
        int periodic_channels;
        int non_periodic_channels;
+       int available_host_channels;
        struct dwc2_host_chan *hc_ptr_array[MAX_EPS_CHANNELS];
        u8 *status_buf;
        dma_addr_t status_buf_dma;
index da0d35cc33ce7dd3bc79245163b27c3f51fd8bbb..83629d84155d569be1c7ed86fb239459e176a90d 100644 (file)
@@ -537,10 +537,15 @@ static void dwc2_hcd_reinit(struct dwc2_hsotg *hsotg)
        int i;
 
        hsotg->flags.d32 = 0;
-
        hsotg->non_periodic_qh_ptr = &hsotg->non_periodic_sched_active;
-       hsotg->non_periodic_channels = 0;
-       hsotg->periodic_channels = 0;
+
+       if (hsotg->core_params->uframe_sched > 0) {
+               hsotg->available_host_channels =
+                       hsotg->core_params->host_channels;
+       } else {
+               hsotg->non_periodic_channels = 0;
+               hsotg->periodic_channels = 0;
+       }
 
        /*
         * Put all channels in the free channel list and clean up channel
@@ -716,8 +721,7 @@ static int dwc2_hc_setup_align_buf(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
  * @qh:    Transactions from the first QTD for this QH are selected and assigned
  *         to a free host channel
  */
-static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg,
-                                   struct dwc2_qh *qh)
+static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 {
        struct dwc2_host_chan *chan;
        struct dwc2_hcd_urb *urb;
@@ -729,18 +733,18 @@ static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg,
 
        if (list_empty(&qh->qtd_list)) {
                dev_dbg(hsotg->dev, "No QTDs in QH list\n");
-               return;
+               return -ENOMEM;
        }
 
        if (list_empty(&hsotg->free_hc_list)) {
                dev_dbg(hsotg->dev, "No free channel to assign\n");
-               return;
+               return -ENOMEM;
        }
 
        chan = list_first_entry(&hsotg->free_hc_list, struct dwc2_host_chan,
                                hc_list_entry);
 
-       /* Remove the host channel from the free list */
+       /* Remove host channel from free list */
        list_del_init(&chan->hc_list_entry);
 
        qtd = list_first_entry(&qh->qtd_list, struct dwc2_qtd, qtd_list_entry);
@@ -780,6 +784,10 @@ static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg,
        chan->data_pid_start = qh->data_toggle;
        chan->multi_count = 1;
 
+       if ((urb->actual_length < 0 || urb->actual_length > urb->length) &&
+           !dwc2_hcd_is_pipe_in(&urb->pipe_info))
+               urb->actual_length = urb->length;
+
        if (hsotg->core_params->dma_enable > 0) {
                chan->xfer_dma = urb->dma + urb->actual_length;
 
@@ -817,7 +825,7 @@ static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg,
                                      &hsotg->free_hc_list);
                        qtd->in_process = 0;
                        qh->channel = NULL;
-                       return;
+                       return -ENOMEM;
                }
        } else {
                chan->align_buf = 0;
@@ -836,6 +844,8 @@ static void dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg,
 
        dwc2_hc_init(hsotg, chan);
        chan->qh = qh;
+
+       return 0;
 }
 
 /**
@@ -864,8 +874,14 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
        while (qh_ptr != &hsotg->periodic_sched_ready) {
                if (list_empty(&hsotg->free_hc_list))
                        break;
+               if (hsotg->core_params->uframe_sched > 0) {
+                       if (hsotg->available_host_channels <= 1)
+                               break;
+                       hsotg->available_host_channels--;
+               }
                qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry);
-               dwc2_assign_and_init_hc(hsotg, qh);
+               if (dwc2_assign_and_init_hc(hsotg, qh))
+                       break;
 
                /*
                 * Move the QH from the periodic ready schedule to the
@@ -884,13 +900,21 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
        num_channels = hsotg->core_params->host_channels;
        qh_ptr = hsotg->non_periodic_sched_inactive.next;
        while (qh_ptr != &hsotg->non_periodic_sched_inactive) {
-               if (hsotg->non_periodic_channels >= num_channels -
+               if (hsotg->core_params->uframe_sched <= 0 &&
+                   hsotg->non_periodic_channels >= num_channels -
                                                hsotg->periodic_channels)
                        break;
                if (list_empty(&hsotg->free_hc_list))
                        break;
                qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry);
-               dwc2_assign_and_init_hc(hsotg, qh);
+               if (hsotg->core_params->uframe_sched > 0) {
+                       if (hsotg->available_host_channels < 1)
+                               break;
+                       hsotg->available_host_channels--;
+               }
+
+               if (dwc2_assign_and_init_hc(hsotg, qh))
+                       break;
 
                /*
                 * Move the QH from the non-periodic inactive schedule to the
@@ -905,7 +929,8 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
                else
                        ret_val = DWC2_TRANSACTION_ALL;
 
-               hsotg->non_periodic_channels++;
+               if (hsotg->core_params->uframe_sched <= 0)
+                       hsotg->non_periodic_channels++;
        }
 
        return ret_val;
@@ -2848,6 +2873,9 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, int irq,
                hsotg->hc_ptr_array[i] = channel;
        }
 
+       if (hsotg->core_params->uframe_sched > 0)
+               dwc2_hcd_init_usecs(hsotg);
+
        /* Initialize hsotg start work */
        INIT_DELAYED_WORK(&hsotg->start_work, dwc2_hcd_start_func);
 
index cc0a117083194c2ec7d962591e9ba41ff4a8e237..89a5484f5b740eeb30f742d4308d212c6cee2480 100644 (file)
@@ -238,6 +238,7 @@ enum dwc2_transaction_type {
  * @interval:           Interval between transfers in (micro)frames
  * @sched_frame:        (Micro)frame to initialize a periodic transfer.
  *                      The transfer executes in the following (micro)frame.
+ * @frame_usecs:        Internal variable used by the microframe scheduler
  * @start_split_frame:  (Micro)frame at which last start split was initialized
  * @ntd:                Actual number of transfer descriptors in a list
  * @dw_align_buf:       Used instead of original buffer if its physical address
@@ -271,6 +272,7 @@ struct dwc2_qh {
        u16 usecs;
        u16 interval;
        u16 sched_frame;
+       u16 frame_usecs[8];
        u16 start_split_frame;
        u16 ntd;
        u8 *dw_align_buf;
@@ -463,6 +465,7 @@ extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
 
 /* Schedule Queue Functions */
 /* Implemented in hcd_queue.c */
+extern void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg);
 extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
 extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
 extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
index 69070f4442a81ad9c7e77cc2b1d1eac0ed5c4bc2..c7d434519776eb4fdf42fa69a5566639dc6a7e06 100644 (file)
@@ -271,10 +271,14 @@ static void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg,
 {
        struct dwc2_host_chan *chan = qh->channel;
 
-       if (dwc2_qh_is_non_per(qh))
-               hsotg->non_periodic_channels--;
-       else
+       if (dwc2_qh_is_non_per(qh)) {
+               if (hsotg->core_params->uframe_sched > 0)
+                       hsotg->available_host_channels++;
+               else
+                       hsotg->non_periodic_channels--;
+       } else {
                dwc2_update_frame_list(hsotg, qh, 0);
+       }
 
        /*
         * The condition is added to prevent double cleanup try in case of
@@ -370,7 +374,8 @@ void dwc2_hcd_qh_free_ddma(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 
        if ((qh->ep_type == USB_ENDPOINT_XFER_ISOC ||
             qh->ep_type == USB_ENDPOINT_XFER_INT) &&
-           !hsotg->periodic_channels && hsotg->frame_list) {
+           (hsotg->core_params->uframe_sched > 0 ||
+            !hsotg->periodic_channels) && hsotg->frame_list) {
                dwc2_per_sched_disable(hsotg);
                dwc2_frame_list_free(hsotg);
        }
index e143f69939f526dd5b8b3115f71aab2e7e9e92bd..cad433a75abae4cb91be0b5ce4271c5ad11286b7 100644 (file)
@@ -748,18 +748,23 @@ cleanup:
        dwc2_hc_cleanup(hsotg, chan);
        list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list);
 
-       switch (chan->ep_type) {
-       case USB_ENDPOINT_XFER_CONTROL:
-       case USB_ENDPOINT_XFER_BULK:
-               hsotg->non_periodic_channels--;
-               break;
-       default:
-               /*
-                * Don't release reservations for periodic channels here.
-                * That's done when a periodic transfer is descheduled (i.e.
-                * when the QH is removed from the periodic schedule).
-                */
-               break;
+       if (hsotg->core_params->uframe_sched > 0) {
+               hsotg->available_host_channels++;
+       } else {
+               switch (chan->ep_type) {
+               case USB_ENDPOINT_XFER_CONTROL:
+               case USB_ENDPOINT_XFER_BULK:
+                       hsotg->non_periodic_channels--;
+                       break;
+               default:
+                       /*
+                        * Don't release reservations for periodic channels
+                        * here. That's done when a periodic transfer is
+                        * descheduled (i.e. when the QH is removed from the
+                        * periodic schedule).
+                        */
+                       break;
+               }
        }
 
        haintmsk = readl(hsotg->regs + HAINTMSK);
index b1980ef28fa30ce2581e7a3516a4e5ee807e5a8d..f200f1f6e1c67ddf3d151552e3aeed0088b5b8f8 100644 (file)
@@ -251,12 +251,12 @@ void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
  *
  * @hsotg: The HCD state structure for the DWC OTG controller
  *
- * Return: 0 if successful, negative error code otherise
+ * Return: 0 if successful, negative error code otherwise
  */
 static int dwc2_periodic_channel_available(struct dwc2_hsotg *hsotg)
 {
        /*
-        * Currently assuming that there is a dedicated host channnel for
+        * Currently assuming that there is a dedicated host channel for
         * each periodic transaction plus at least one host channel for
         * non-periodic transactions
         */
@@ -323,6 +323,146 @@ static int dwc2_check_periodic_bandwidth(struct dwc2_hsotg *hsotg,
        return status;
 }
 
+/**
+ * Microframe scheduler
+ * track the total use in hsotg->frame_usecs
+ * keep each qh use in qh->frame_usecs
+ * when surrendering the qh then donate the time back
+ */
+static const unsigned short max_uframe_usecs[] = {
+       100, 100, 100, 100, 100, 100, 30, 0
+};
+
+void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg)
+{
+       int i;
+
+       for (i = 0; i < 8; i++)
+               hsotg->frame_usecs[i] = max_uframe_usecs[i];
+}
+
+static int dwc2_find_single_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
+{
+       unsigned short utime = qh->usecs;
+       int done = 0;
+       int i = 0;
+       int ret = -1;
+
+       while (!done) {
+               /* At the start hsotg->frame_usecs[i] = max_uframe_usecs[i] */
+               if (utime <= hsotg->frame_usecs[i]) {
+                       hsotg->frame_usecs[i] -= utime;
+                       qh->frame_usecs[i] += utime;
+                       ret = i;
+                       done = 1;
+               } else {
+                       i++;
+                       if (i == 8)
+                               done = 1;
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * use this for FS apps that can span multiple uframes
+ */
+static int dwc2_find_multi_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
+{
+       unsigned short utime = qh->usecs;
+       unsigned short xtime;
+       int t_left = utime;
+       int done = 0;
+       int i = 0;
+       int j;
+       int ret = -1;
+
+       while (!done) {
+               if (hsotg->frame_usecs[i] <= 0) {
+                       i++;
+                       if (i == 8) {
+                               ret = -1;
+                               done = 1;
+                       }
+                       continue;
+               }
+
+               /*
+                * we need n consecutive slots so use j as a start slot
+                * j plus j+1 must be enough time (for now)
+                */
+               xtime = hsotg->frame_usecs[i];
+               for (j = i + 1; j < 8; j++) {
+                       /*
+                        * if we add this frame remaining time to xtime we may
+                        * be OK, if not we need to test j for a complete frame
+                        */
+                       if (xtime + hsotg->frame_usecs[j] < utime) {
+                               if (hsotg->frame_usecs[j] <
+                                                       max_uframe_usecs[j]) {
+                                       ret = -1;
+                                       break;
+                               }
+                       }
+                       if (xtime >= utime) {
+                               ret = i;
+                               break;
+                       }
+                       /* add the frame time to x time */
+                       xtime += hsotg->frame_usecs[j];
+                       /* we must have a fully available next frame or break */
+                       if (xtime < utime &&
+                          hsotg->frame_usecs[j] == max_uframe_usecs[j]) {
+                               ret = -1;
+                               break;
+                       }
+               }
+               if (ret >= 0) {
+                       t_left = utime;
+                       for (j = i; t_left > 0 && j < 8; j++) {
+                               t_left -= hsotg->frame_usecs[j];
+                               if (t_left <= 0) {
+                                       qh->frame_usecs[j] +=
+                                               hsotg->frame_usecs[j] + t_left;
+                                       hsotg->frame_usecs[j] = -t_left;
+                                       ret = i;
+                                       done = 1;
+                               } else {
+                                       qh->frame_usecs[j] +=
+                                               hsotg->frame_usecs[j];
+                                       hsotg->frame_usecs[j] = 0;
+                               }
+                       }
+               } else {
+                       i++;
+                       if (i == 8) {
+                               ret = -1;
+                               done = 1;
+                       }
+               }
+       }
+
+       return ret;
+}
+
+static int dwc2_find_uframe(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
+{
+       int ret;
+
+       if (qh->dev_speed == USB_SPEED_HIGH) {
+               /* if this is a hs transaction we need a full frame */
+               ret = dwc2_find_single_uframe(hsotg, qh);
+       } else {
+               /*
+                * if this is a fs transaction we may need a sequence
+                * of frames
+                */
+               ret = dwc2_find_multi_uframe(hsotg, qh);
+       }
+       return ret;
+}
+
 /**
  * dwc2_check_max_xfer_size() - Checks that the max transfer size allowed in a
  * host channel is large enough to handle the maximum data transfer in a single
@@ -367,15 +507,35 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 {
        int status;
 
-       status = dwc2_periodic_channel_available(hsotg);
-       if (status) {
-               dev_dbg(hsotg->dev,
-                       "%s: No host channel available for periodic transfer\n",
-                       __func__);
-               return status;
+       if (hsotg->core_params->uframe_sched > 0) {
+               int frame = -1;
+
+               status = dwc2_find_uframe(hsotg, qh);
+               if (status == 0)
+                       frame = 7;
+               else if (status > 0)
+                       frame = status - 1;
+
+               /* Set the new frame up */
+               if (frame > -1) {
+                       qh->sched_frame &= ~0x7;
+                       qh->sched_frame |= (frame & 7);
+               }
+
+               if (status != -1)
+                       status = 0;
+       } else {
+               status = dwc2_periodic_channel_available(hsotg);
+               if (status) {
+                       dev_info(hsotg->dev,
+                                "%s: No host channel available for periodic transfer\n",
+                                __func__);
+                       return status;
+               }
+
+               status = dwc2_check_periodic_bandwidth(hsotg, qh);
        }
 
-       status = dwc2_check_periodic_bandwidth(hsotg, qh);
        if (status) {
                dev_dbg(hsotg->dev,
                        "%s: Insufficient periodic bandwidth for periodic transfer\n",
@@ -399,8 +559,9 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
                list_add_tail(&qh->qh_list_entry,
                              &hsotg->periodic_sched_inactive);
 
-       /* Reserve periodic channel */
-       hsotg->periodic_channels++;
+       if (hsotg->core_params->uframe_sched <= 0)
+               /* Reserve periodic channel */
+               hsotg->periodic_channels++;
 
        /* Update claimed usecs per (micro)frame */
        hsotg->periodic_usecs += qh->usecs;
@@ -418,13 +579,22 @@ static int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
 static void dwc2_deschedule_periodic(struct dwc2_hsotg *hsotg,
                                     struct dwc2_qh *qh)
 {
-       list_del_init(&qh->qh_list_entry);
+       int i;
 
-       /* Release periodic channel reservation */
-       hsotg->periodic_channels--;
+       list_del_init(&qh->qh_list_entry);
 
        /* Update claimed usecs per (micro)frame */
        hsotg->periodic_usecs -= qh->usecs;
+
+       if (hsotg->core_params->uframe_sched > 0) {
+               for (i = 0; i < 8; i++) {
+                       hsotg->frame_usecs[i] += qh->frame_usecs[i];
+                       qh->frame_usecs[i] = 0;
+               }
+       } else {
+               /* Release periodic channel reservation */
+               hsotg->periodic_channels--;
+       }
 }
 
 /**
@@ -581,7 +751,10 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
                         * Remove from periodic_sched_queued and move to
                         * appropriate queue
                         */
-                       if (qh->sched_frame == frame_number)
+                       if ((hsotg->core_params->uframe_sched > 0 &&
+                            dwc2_frame_num_le(qh->sched_frame, frame_number))
+                        || (hsotg->core_params->uframe_sched <= 0 &&
+                            qh->sched_frame == frame_number))
                                list_move(&qh->qh_list_entry,
                                          &hsotg->periodic_sched_ready);
                        else
index 9020260d5df8f96b53ff1697f6b0f568341be3bd..3d14c8870fcac75f6f1e6af1ef315b49c23778a7 100644 (file)
@@ -84,6 +84,7 @@ static const struct dwc2_core_params dwc2_module_params = {
        .ts_dline                       = -1,
        .reload_ctl                     = -1,
        .ahbcfg                         = -1,
+       .uframe_sched                   = -1,
 };
 
 /**
diff --git a/drivers/staging/et131x/Module.symvers b/drivers/staging/et131x/Module.symvers
new file mode 100644 (file)
index 0000000..e69de29
index 9272a24ae61c8250ba770acf8f85e69c610d0f99..8da96a6d2c927946d0c1444fca0472904af7b21b 100644 (file)
@@ -11,7 +11,12 @@ TODO:
        - Look at reducing the number of spinlocks
        - Simplify code in nic_rx_pkts(), when determining multicast_pkts_rcvd
        - Implement NAPI support
-       - in et131x_tx(), don't return NETDEV_TX_BUSY, just drop the packet with          kfree_skb().
+       - In et131x_tx(), don't return NETDEV_TX_BUSY, just drop the packet with kfree_skb().
+       - Reduce the number of split lines by careful consideration of variable names etc.
+       - Do this in et131x.c:
+                struct fbr_lookup *fbr;
+                fbr = rx_local->fbr[id];
+         Then replace all the instances of "rx_local->fbr[id]" with fbr.
 
 Please send patches to:
        Greg Kroah-Hartman <gregkh@linuxfoundation.org>
index 61da7ee36e458ccd73a634839f5feda5a3d00808..51a39d55ff665d61816f8c804af6dbd0bbdacf73 100644 (file)
@@ -493,11 +493,8 @@ struct et131x_adapter {
        spinlock_t send_hw_lock;
 
        spinlock_t rcv_lock;
-       spinlock_t rcv_pend_lock;
        spinlock_t fbr_lock;
 
-       spinlock_t phy_lock;
-
        /* Packet Filter and look ahead size */
        u32 packet_filter;
 
@@ -2777,10 +2774,9 @@ static void et131x_handle_recv_interrupt(struct et131x_adapter *adapter)
                adapter->net_stats.rx_packets++;
 
                /* Set the status on the packet, either resources or success */
-               if (adapter->rx_ring.num_ready_recv < RFD_LOW_WATER_MARK) {
-                       dev_warn(&adapter->pdev->dev,
-                                   "RFD's are running out\n");
-               }
+               if (adapter->rx_ring.num_ready_recv < RFD_LOW_WATER_MARK)
+                       dev_warn(&adapter->pdev->dev, "RFD's are running out\n");
+
                count++;
        }
 
@@ -3100,11 +3096,10 @@ static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter)
                shbufva = (u16 *) skb->data;
 
                if ((shbufva[0] == 0xffff) &&
-                   (shbufva[1] == 0xffff) && (shbufva[2] == 0xffff)) {
+                   (shbufva[1] == 0xffff) && (shbufva[2] == 0xffff))
                        tcb->flags |= FMP_DEST_BROAD;
-               } else if ((shbufva[0] & 0x3) == 0x0001) {
+               else if ((shbufva[0] & 0x3) == 0x0001)
                        tcb->flags |=  FMP_DEST_MULTI;
-               }
        }
 
        tcb->next = NULL;
@@ -3926,9 +3921,7 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev,
        spin_lock_init(&adapter->tcb_ready_qlock);
        spin_lock_init(&adapter->send_hw_lock);
        spin_lock_init(&adapter->rcv_lock);
-       spin_lock_init(&adapter->rcv_pend_lock);
        spin_lock_init(&adapter->fbr_lock);
-       spin_lock_init(&adapter->phy_lock);
 
        adapter->registry_jumbo_packet = 1514;  /* 1514-9216 */
 
index b2330f1df7e7066ab15aae5707a79f6fc7b32b2e..88f6f9ce304a57ad2c433e642c4d04e313b505bb 100644 (file)
 
 #define seq_putx(m, message, size, var) \
        seq_printf(m, message); \
-       for(i = 0; i < (size - 1); i++) { \
+       for (i = 0; i < (size - 1); i++) { \
                seq_printf(m, "%02x:", var[i]); \
        } \
        seq_printf(m, "%02x\n", var[i])
 
 #define seq_putd(m, message, size, var) \
        seq_printf(m, message); \
-       for(i = 0; i < (size - 1); i++) { \
+       for (i = 0; i < (size - 1); i++) { \
                seq_printf(m, "%d.", var[i]); \
        } \
        seq_printf(m, "%d\n", var[i])
index 5190c8ac4e0a77cbb03e4f5b4d14c4dd764469a0..1a1413d31af651e62a3fd0cd452b7cd4bbca16b6 100644 (file)
@@ -1,12 +1,8 @@
-//=====================================================
-// CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
-//
-//
-// This file is part of Express Card USB Driver
-//
-// $Id:
-//====================================================
-// 20090926; aelias; removed compiler warnings; ubuntu 9.04; 2.6.28-15-generic
+/*
+* CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved.
+*
+* This file is part of Express Card USB Driver
+*/
 
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -111,19 +107,8 @@ struct dsp_image_info {
 };
 
 
-//---------------------------------------------------------------------------
-// Function:    check_usb_db
-//
-// Parameters:  struct ft1000_usb  - device structure
-//
-// Returns:     0 - success
-//
-// Description: This function checks if the doorbell register is cleared
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
-static u32 check_usb_db (struct ft1000_usb *ft1000dev)
+/* checks if the doorbell register is cleared */
+static u32 check_usb_db(struct ft1000_usb *ft1000dev)
 {
        int loopcnt;
        u16 temp;
@@ -169,20 +154,7 @@ static u32 check_usb_db (struct ft1000_usb *ft1000dev)
        return HANDSHAKE_MAG_TIMEOUT_VALUE;
 }
 
-//---------------------------------------------------------------------------
-// Function:    get_handshake
-//
-// Parameters:  struct ft1000_usb  - device structure
-//              u16 expected_value - the handshake value expected
-//
-// Returns:     handshakevalue - success
-//              HANDSHAKE_TIMEOUT_VALUE - failure
-//
-// Description: This function gets the handshake and compare with the expected value
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* gets the handshake and compares it with the expected value */
 static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value)
 {
        u16 handshake;
@@ -229,20 +201,7 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value)
        return HANDSHAKE_TIMEOUT_VALUE;
 }
 
-//---------------------------------------------------------------------------
-// Function:    put_handshake
-//
-// Parameters:  struct ft1000_usb  - device structure
-//              u16 handshake_value - handshake to be written
-//
-// Returns:     none
-//
-// Description: This function write the handshake value to the handshake location
-//              in DPRAM
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* write the handshake value to the handshake location */
 static void put_handshake(struct ft1000_usb *ft1000dev,u16 handshake_value)
 {
        u32 tempx;
@@ -316,18 +275,6 @@ static void put_handshake_usb(struct ft1000_usb *ft1000dev,u16 handshake_value)
         for (i=0; i<1000; i++);
 }
 
-//---------------------------------------------------------------------------
-// Function:    get_request_type
-//
-// Parameters:  struct ft1000_usb  - device structure
-//
-// Returns:     request type - success
-//
-// Description: This function returns the request type
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
 static u16 get_request_type(struct ft1000_usb *ft1000dev)
 {
        u16 request_type;
@@ -380,18 +327,6 @@ static u16 get_request_type_usb(struct ft1000_usb *ft1000dev)
        return request_type;
 }
 
-//---------------------------------------------------------------------------
-// Function:    get_request_value
-//
-// Parameters:  struct ft1000_usb  - device structure
-//
-// Returns:     request value - success
-//
-// Description: This function returns the request value
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
 static long get_request_value(struct ft1000_usb *ft1000dev)
 {
        u32 value;
@@ -416,19 +351,7 @@ static long get_request_value(struct ft1000_usb *ft1000dev)
 }
 
 
-//---------------------------------------------------------------------------
-// Function:    put_request_value
-//
-// Parameters:  struct ft1000_usb  - device structure
-//              long lvalue - value to be put into DPRAM location DWNLD_MAG1_SIZE_LOC
-//
-// Returns:     none
-//
-// Description: This function writes a value to DWNLD_MAG1_SIZE_LOC
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* writes a value to DWNLD_MAG1_SIZE_LOC */
 static void put_request_value(struct ft1000_usb *ft1000dev, long lvalue)
 {
        u32    tempx;
@@ -441,18 +364,7 @@ static void put_request_value(struct ft1000_usb *ft1000dev, long lvalue)
 
 
 
-//---------------------------------------------------------------------------
-// Function:    hdr_checksum
-//
-// Parameters:  struct pseudo_hdr *pHdr - Pseudo header pointer
-//
-// Returns:     checksum - success
-//
-// Description: This function returns the checksum of the pseudo header
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* returns the checksum of the pseudo header */
 static u16 hdr_checksum(struct pseudo_hdr *pHdr)
 {
        u16   *usPtr = (u16 *)pHdr;
@@ -477,23 +389,12 @@ static int check_buffers(u16 *buff_w, u16 *buff_r, int len, int offset)
        return 0;
 }
 
-//---------------------------------------------------------------------------
-// Function:    write_blk
-//
-// Parameters:  struct ft1000_usb  - device structure
-//              u16 **pUsFile - DSP image file pointer in u16
-//              u8  **pUcFile - DSP image file pointer in u8
-//              long   word_length - length of the buffer to be written
-//                                   to DPRAM
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function writes a block of DSP image to DPRAM
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* writes a block of DSP image to DPRAM
+ * Parameters:  struct ft1000_usb  - device structure
+ *              u16 **pUsFile - DSP image file pointer in u16
+ *              u8  **pUcFile - DSP image file pointer in u8
+ *              long word_length - length of the buffer to be written to DPRAM
+ */
 static u32 write_blk (struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length)
 {
    u32 Status = STATUS_SUCCESS;
@@ -616,23 +517,12 @@ static void usb_dnld_complete (struct urb *urb)
     //DEBUG("****** usb_dnld_complete\n");
 }
 
-//---------------------------------------------------------------------------
-// Function:    write_blk_fifo
-//
-// Parameters:  struct ft1000_usb  - device structure
-//              u16 **pUsFile - DSP image file pointer in u16
-//              u8  **pUcFile - DSP image file pointer in u8
-//              long   word_length - length of the buffer to be written
-//                                   to DPRAM
-//
-// Returns:     STATUS_SUCCESS - success
-//              STATUS_FAILURE - failure
-//
-// Description: This function writes a block of DSP image to DPRAM
-//
-// Notes:
-//
-//---------------------------------------------------------------------------
+/* writes a block of DSP image to DPRAM
+ * Parameters:  struct ft1000_usb  - device structure
+ *              u16 **pUsFile - DSP image file pointer in u16
+ *              u8  **pUcFile - DSP image file pointer in u8
+ *              long word_length - length of the buffer to be written to DPRAM
+ */
 static u32 write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile,
                          u8 **pUcFile, long word_length)
 {
@@ -664,18 +554,7 @@ static u32 write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile,
        return Status;
 }
 
-//---------------------------------------------------------------------------
-//
-//  Function:   scram_dnldr
-//
-//  Synopsis:   Scramble downloader for Harley based ASIC via USB interface
-//
-//  Arguments:  pFileStart              - pointer to start of file
-//              FileLength              - file length
-//
-//  Returns:    status                  - return code
-//---------------------------------------------------------------------------
-
+/* Scramble downloader for Harley based ASIC via USB interface */
 u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                u32 FileLength)
 {
@@ -1036,7 +915,7 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                                                status =
                                                    fix_ft1000_write_dpram32
                                                    (ft1000dev, dpram++,
-                                                    (u8 *) & templong);
+                                                    (u8 *) &templong);
 
                                        }
                                        break;
@@ -1137,13 +1016,13 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                        if (pseudo_header->checksum ==
                            hdr_checksum(pseudo_header)) {
                                if (pseudo_header->portdest !=
-                                   0x80 /* Dsp OAM */ ) {
+                                   0x80 /* Dsp OAM */) {
                                        state = STATE_DONE_PROV;
                                        break;
                                }
                                pseudo_header_len = ntohs(pseudo_header->length);       /* Byte length for PROV records */
 
-                               // Get buffer for provisioning data
+                               /* Get buffer for provisioning data */
                                pbuffer =
                                    kmalloc((pseudo_header_len +
                                             sizeof(struct pseudo_hdr)),
@@ -1201,9 +1080,8 @@ u16 scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart,
                        break;
                }               /* End Switch */
 
-               if (status != STATUS_SUCCESS) {
+               if (status != STATUS_SUCCESS)
                        break;
-               }
 
 /****
       // Check if Card is present
index ff92f34e4746f3e9e0239abe945c866115e86605..62df009e5ac7c8e9bcd5779bf57e9b8c1d2c309d 100644 (file)
@@ -2394,7 +2394,8 @@ static int fwserial_create(struct fw_unit *unit)
 
        list_del_rcu(&serial->list);
        if (create_loop_dev)
-               tty_unregister_device(fwloop_driver, loop_idx(serial->ports[j]));
+               tty_unregister_device(fwloop_driver,
+                                     loop_idx(serial->ports[j]));
 unregister_ttys:
        for (--j; j >= 0; --j)
                tty_unregister_device(fwtty_driver, serial->ports[j]->index);
index bc0d510fb0af3539033fdf11642bd820627c5083..c57a6ba5d010e84464632590c20e48e805d8681e 100644 (file)
@@ -110,7 +110,7 @@ static int gdm_lte_rx(struct sk_buff *skb, struct nic *nic, int nic_type)
        return 0;
 }
 
-int gdm_lte_emulate_arp(struct sk_buff *skb_in, u32 nic_type)
+static int gdm_lte_emulate_arp(struct sk_buff *skb_in, u32 nic_type)
 {
        struct nic *nic = netdev_priv(skb_in->dev);
        struct sk_buff *skb_out;
@@ -186,7 +186,7 @@ int gdm_lte_emulate_arp(struct sk_buff *skb_in, u32 nic_type)
        return 0;
 }
 
-int icmp6_checksum(struct ipv6hdr *ipv6, u16 *ptr, int len)
+static int icmp6_checksum(struct ipv6hdr *ipv6, u16 *ptr, int len)
 {
        unsigned short *w = ptr;
        int sum = 0;
@@ -226,7 +226,7 @@ int icmp6_checksum(struct ipv6hdr *ipv6, u16 *ptr, int len)
        return sum;
 }
 
-int gdm_lte_emulate_ndp(struct sk_buff *skb_in, u32 nic_type)
+static int gdm_lte_emulate_ndp(struct sk_buff *skb_in, u32 nic_type)
 {
        struct nic *nic = netdev_priv(skb_in->dev);
        struct sk_buff *skb_out;
index 5b1ef4000d0fe4a06086fb5ca8e7a14c896b653f..62163673976c309e93f004ba5082b80f2a8f240d 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "gdm_mux.h"
 
-struct workqueue_struct *mux_rx_wq;
+static struct workqueue_struct *mux_rx_wq;
 
 static u16 packet_type[TTY_MAX_COUNT] = {0xF011, 0xF010};
 
@@ -51,7 +51,7 @@ static const struct usb_device_id id_table[] = {
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-int packet_type_to_index(u16 packetType)
+static int packet_type_to_index(u16 packetType)
 {
        int i;
 
@@ -96,12 +96,12 @@ static struct mux_rx *alloc_mux_rx(void)
 {
        struct mux_rx *r = NULL;
 
-       r = kzalloc(sizeof(struct mux_rx), GFP_ATOMIC);
+       r = kzalloc(sizeof(struct mux_rx), GFP_KERNEL);
        if (!r)
                return NULL;
 
-       r->urb = usb_alloc_urb(0, GFP_ATOMIC);
-       r->buf = kmalloc(MUX_RX_MAX_SIZE, GFP_ATOMIC);
+       r->urb = usb_alloc_urb(0, GFP_KERNEL);
+       r->buf = kmalloc(MUX_RX_MAX_SIZE, GFP_KERNEL);
        if (!r->urb || !r->buf) {
                usb_free_urb(r->urb);
                kfree(r->buf);
@@ -541,7 +541,7 @@ static int gdm_mux_probe(struct usb_interface *intf, const struct usb_device_id
 
        ret = init_usb(mux_dev);
        if (ret)
-               goto err_free_tty;
+               goto err_free_usb;
 
        tty_dev->priv_dev = (void *)mux_dev;
        tty_dev->send_func = gdm_mux_send;
@@ -565,8 +565,8 @@ static int gdm_mux_probe(struct usb_interface *intf, const struct usb_device_id
 
 err_unregister_tty:
        unregister_lte_tty_device(tty_dev);
+err_free_usb:
        release_usb(mux_dev);
-err_free_tty:
        kfree(tty_dev);
 err_free_mux:
        kfree(mux_dev);
index 0247a2055e8d68097388c6aaf9331a6b5ea4800c..c0f7cd75116b1f294b90b6373cdb594e07a2c53e 100644 (file)
@@ -171,7 +171,8 @@ static void gdm_tty_send_complete(void *arg)
        tty_port_tty_wakeup(&gdm->port);
 }
 
-static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, int len)
+static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf,
+                        int len)
 {
        struct gdm *gdm = tty->driver_data;
        int remain = len;
@@ -185,7 +186,8 @@ static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, int l
                return 0;
 
        while (1) {
-               sending_len = remain > MUX_TX_MAX_SIZE ? MUX_TX_MAX_SIZE : remain;
+               sending_len = remain > MUX_TX_MAX_SIZE ? MUX_TX_MAX_SIZE :
+                                                        remain;
                gdm_tty_send(gdm,
                             (void *)(buf+sent_len),
                             sending_len,
@@ -247,7 +249,8 @@ int register_lte_tty_device(struct tty_dev *tty_dev, struct device *device)
                gdm->minor = j;
                gdm->tty_dev = tty_dev;
 
-               tty_port_register_device(&gdm->port, gdm_driver[i], gdm->minor, device);
+               tty_port_register_device(&gdm->port, gdm_driver[i],
+                                        gdm->minor, device);
        }
 
        for (i = 0; i < MAX_ISSUE_NUM; i++)
@@ -309,7 +312,8 @@ int register_lte_tty_driver(void)
                tty_driver->major = GDM_TTY_MAJOR;
                tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
                tty_driver->subtype = SERIAL_TYPE_NORMAL;
-               tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+               tty_driver->flags = TTY_DRIVER_REAL_RAW |
+                                       TTY_DRIVER_DYNAMIC_DEV;
                tty_driver->init_termios = tty_std_termios;
                tty_driver->init_termios.c_cflag = B9600 | CS8 | HUPCL | CLOCAL;
                tty_driver->init_termios.c_lflag = ISIG | ICANON | IEXTEN;
index cf32ae099cd68aef662b78f92936cd8cfc657265..35154d60faf6120813bb26bf2477994e66fd259f 100644 (file)
@@ -502,7 +502,7 @@ inline int find_type_by_name(const char *name, const char *type)
 
 inline int _write_sysfs_int(char *filename, char *basedir, int val, int verify)
 {
-       int ret;
+       int ret = 0;
        FILE *sysfsfp;
        int test;
        char *temp = malloc(strlen(basedir) + strlen(filename) + 2);
index 04c23262f8e201a8a52ce8a0e7de0f0542891059..c22a0edd1528776f359ec321b5d72ba94bacb839 100644 (file)
@@ -13,6 +13,17 @@ Would be nice
 3) Expand device set. Lots of other maxim adc's have very
    similar interfaces.
 
+MXS LRADC driver:
+This is a classic MFD device as it combines the following subdevices
+ - touchscreen controller (input subsystem related device)
+ - general purpose ADC channels
+ - battery voltage monitor (power subsystem related device)
+ - die temperature monitor (thermal management)
+
+At least the battery voltage and die temperature feature is required in-kernel
+by a driver of the SoC's battery charging unit to avoid any damage to the
+silicon and the battery.
+
 TSL2561
 Would be nice
 1) Open question of userspace vs kernel space balance when
index 5c289614357c578e9df243c3b0b03572bbbf5c3e..4c9364b63c77d61a1088298993ad46435c0cca6e 100644 (file)
@@ -102,7 +102,6 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
                                        int addr)
 {
        struct adis16220_state *st = iio_priv(indio_dev);
-       struct spi_message msg;
        struct spi_transfer xfers[] = {
                {
                        .tx_buf = st->tx,
@@ -147,10 +146,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev,
        }
        xfers[1].len = count;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfers[0], &msg);
-       spi_message_add_tail(&xfers[1], &msg);
-       ret = spi_sync(st->adis.spi, &msg);
+       ret = spi_sync_transfer(st->adis.spi, xfers, ARRAY_SIZE(xfers));
        if (ret) {
 
                mutex_unlock(&st->buf_lock);
index bb852dc9c9870c703d261734f5408770758cbb75..2789be381f1b166072d0cef2f6fd0ca3f95f60c0 100644 (file)
@@ -190,15 +190,26 @@ static u8 lis3l02dq_axis_map[3][3] = {
 };
 
 static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
-                                u64 e,
-                                int *val)
+                                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)
 {
-       return lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
+       int ret;
+
+       ret = lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
+       if (ret)
+               return ret;
+       return IIO_VAL_INT;
 }
 
 static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
-                                 u64 event_code,
-                                 int val)
+                                 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)
 {
        u16 value = val;
        return lis3l02dq_spi_write_reg_s16(indio_dev,
@@ -503,9 +514,19 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
        return IRQ_HANDLED;
 }
 
-#define LIS3L02DQ_EVENT_MASK                                   \
-       (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |    \
-        IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+static const struct iio_event_spec lis3l02dq_event[] = {
+       {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_ENABLE),
+               .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_ENABLE),
+               .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
+       }
+};
 
 #define LIS3L02DQ_CHAN(index, mod)                             \
        {                                                       \
@@ -523,7 +544,8 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
                        .realbits = 12,                         \
                        .storagebits = 16,                      \
                },                                              \
-               .event_mask = LIS3L02DQ_EVENT_MASK,             \
+               .event_spec = lis3l02dq_event,                  \
+               .num_event_specs = ARRAY_SIZE(lis3l02dq_event), \
         }
 
 static const struct iio_chan_spec lis3l02dq_channels[] = {
@@ -535,14 +557,14 @@ static const struct iio_chan_spec lis3l02dq_channels[] = {
 
 
 static int lis3l02dq_read_event_config(struct iio_dev *indio_dev,
-                                          u64 event_code)
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir)
 {
 
        u8 val;
        int ret;
-       u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
-                        (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                         IIO_EV_DIR_RISING)));
+       u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
        ret = lis3l02dq_spi_read_reg_8(indio_dev,
                                       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
                                       &val);
@@ -587,16 +609,16 @@ error_ret:
 }
 
 static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
-                                       u64 event_code,
+                                       const struct iio_chan_spec *chan,
+                                       enum iio_event_type type,
+                                       enum iio_event_direction dir,
                                        int state)
 {
        int ret = 0;
        u8 val, control;
        u8 currentlyset;
        bool changed = false;
-       u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
-                        (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                         IIO_EV_DIR_RISING)));
+       u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
 
        mutex_lock(&indio_dev->mlock);
        /* read current control */
@@ -654,10 +676,10 @@ static const struct attribute_group lis3l02dq_attribute_group = {
 static const struct iio_info lis3l02dq_info = {
        .read_raw = &lis3l02dq_read_raw,
        .write_raw = &lis3l02dq_write_raw,
-       .read_event_value = &lis3l02dq_read_thresh,
-       .write_event_value = &lis3l02dq_write_thresh,
-       .write_event_config = &lis3l02dq_write_event_config,
-       .read_event_config = &lis3l02dq_read_event_config,
+       .read_event_value_new = &lis3l02dq_read_thresh,
+       .write_event_value_new = &lis3l02dq_write_thresh,
+       .write_event_config_new = &lis3l02dq_write_event_config,
+       .read_event_config_new = &lis3l02dq_read_event_config,
        .driver_module = THIS_MODULE,
        .attrs = &lis3l02dq_attribute_group,
 };
index 5b8f0f6c99385d409ba471acfe902a041518da38..79cefe0a516a7316269546a36c2eec1fb3648556 100644 (file)
@@ -111,7 +111,7 @@ static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev,
                                u8 *buf)
 {
        int ret, i;
-       u8 *rx_array ;
+       u8 *rx_array;
        s16 *data = (s16 *)buf;
        int scan_count = bitmap_weight(indio_dev->active_scan_mask,
                                       indio_dev->masklength);
@@ -146,11 +146,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
        if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
                len = lis3l02dq_get_buffer_element(indio_dev, data);
 
-         /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp)
-               *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
-                       = pf->timestamp;
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+       iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
 
        kfree(data);
 done:
@@ -264,8 +260,7 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
                else
                        break;
        if (i == 5)
-               printk(KERN_INFO
-                      "Failed to clear the interrupt for lis3l02dq\n");
+               pr_info("Failed to clear the interrupt for lis3l02dq\n");
 
        /* irq reenabled so success! */
        return 0;
@@ -387,7 +382,6 @@ error_ret:
 }
 
 static const struct iio_buffer_setup_ops lis3l02dq_buffer_setup_ops = {
-       .preenable = &iio_sw_buffer_preenable,
        .postenable = &lis3l02dq_buffer_postenable,
        .predisable = &lis3l02dq_buffer_predisable,
 };
@@ -401,7 +395,7 @@ int lis3l02dq_configure_buffer(struct iio_dev *indio_dev)
        if (!buffer)
                return -ENOMEM;
 
-       indio_dev->buffer = buffer;
+       iio_device_attach_buffer(indio_dev, buffer);
 
        buffer->scan_timestamp = true;
        indio_dev->setup_ops = &lis3l02dq_buffer_setup_ops;
index 48a25ba290f5ae8a19c18c824a155c082321c66e..c49e6ef9d05f866fe6bacc56bdbeab9dd44b6b4a 100644 (file)
@@ -419,8 +419,11 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR,
 
 static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);
 
-#define SCA3000_EVENT_MASK                                     \
-       (IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING))
+static const struct iio_event_spec sca3000_event = {
+       .type = IIO_EV_TYPE_MAG,
+       .dir = IIO_EV_DIR_RISING,
+       .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
 
 #define SCA3000_CHAN(index, mod)                               \
        {                                                       \
@@ -437,7 +440,8 @@ static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0);
                        .storagebits = 16,                      \
                        .shift = 5,                             \
                },                                              \
-               .event_mask = SCA3000_EVENT_MASK,               \
+               .event_spec = &sca3000_event,                   \
+               .num_event_specs = 1,                           \
         }
 
 static const struct iio_chan_spec sca3000_channels[] = {
@@ -624,9 +628,9 @@ static ssize_t sca3000_set_frequency(struct device *dev,
        struct sca3000_state *st = iio_priv(indio_dev);
        int ret, base_freq = 0;
        int ctrlval;
-       long val;
+       int val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtoint(buf, 10, &val);
        if (ret)
                return ret;
 
@@ -703,12 +707,15 @@ static IIO_CONST_ATTR_TEMP_OFFSET("-214.6");
  * sca3000_read_thresh() - query of a threshold
  **/
 static int sca3000_read_thresh(struct iio_dev *indio_dev,
-                              u64 e,
-                              int *val)
+                              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)
 {
        int ret, i;
        struct sca3000_state *st = iio_priv(indio_dev);
-       int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+       int num = chan->channel2;
        mutex_lock(&st->lock);
        ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]);
        mutex_unlock(&st->lock);
@@ -724,18 +731,21 @@ static int sca3000_read_thresh(struct iio_dev *indio_dev,
                                 ARRAY_SIZE(st->info->mot_det_mult_xz))
                        *val += st->info->mot_det_mult_xz[i];
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
 /**
  * sca3000_write_thresh() control of threshold
  **/
 static int sca3000_write_thresh(struct iio_dev *indio_dev,
-                               u64 e,
-                               int val)
+                               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 sca3000_state *st = iio_priv(indio_dev);
-       int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+       int num = chan->channel2;
        int ret;
        int i;
        u8 nonlinear = 0;
@@ -866,12 +876,14 @@ done:
  * sca3000_read_event_config() what events are enabled
  **/
 static int sca3000_read_event_config(struct iio_dev *indio_dev,
-                                    u64 e)
+                                    const struct iio_chan_spec *chan,
+                                    enum iio_event_type type,
+                                    enum iio_event_direction dir)
 {
        struct sca3000_state *st = iio_priv(indio_dev);
        int ret;
        u8 protect_mask = 0x03;
-       int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+       int num = chan->channel2;
 
        /* read current value of mode register */
        mutex_lock(&st->lock);
@@ -931,12 +943,12 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct sca3000_state *st = iio_priv(indio_dev);
-       long val;
+       u8 val;
        int ret;
        u8 protect_mask = SCA3000_FREE_FALL_DETECT;
 
        mutex_lock(&st->lock);
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
 
@@ -969,13 +981,15 @@ error_ret:
  * this mode is disabled.  Currently normal mode is assumed.
  **/
 static int sca3000_write_event_config(struct iio_dev *indio_dev,
-                                     u64 e,
+                                     const struct iio_chan_spec *chan,
+                                     enum iio_event_type type,
+                                     enum iio_event_direction dir,
                                      int state)
 {
        struct sca3000_state *st = iio_priv(indio_dev);
        int ret, ctrlval;
        u8 protect_mask = 0x03;
-       int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
+       int num = chan->channel2;
 
        mutex_lock(&st->lock);
        /* First read the motion detector config to find out if
@@ -1112,20 +1126,20 @@ static const struct iio_info sca3000_info = {
        .attrs = &sca3000_attribute_group,
        .read_raw = &sca3000_read_raw,
        .event_attrs = &sca3000_event_attribute_group,
-       .read_event_value = &sca3000_read_thresh,
-       .write_event_value = &sca3000_write_thresh,
-       .read_event_config = &sca3000_read_event_config,
-       .write_event_config = &sca3000_write_event_config,
+       .read_event_value_new = &sca3000_read_thresh,
+       .write_event_value_new = &sca3000_write_thresh,
+       .read_event_config_new = &sca3000_read_event_config,
+       .write_event_config_new = &sca3000_write_event_config,
        .driver_module = THIS_MODULE,
 };
 
 static const struct iio_info sca3000_info_with_temp = {
        .attrs = &sca3000_attribute_group_with_temp,
        .read_raw = &sca3000_read_raw,
-       .read_event_value = &sca3000_read_thresh,
-       .write_event_value = &sca3000_write_thresh,
-       .read_event_config = &sca3000_read_event_config,
-       .write_event_config = &sca3000_write_event_config,
+       .read_event_value_new = &sca3000_read_thresh,
+       .write_event_value_new = &sca3000_write_thresh,
+       .read_event_config_new = &sca3000_read_event_config,
+       .write_event_config_new = &sca3000_write_event_config,
        .driver_module = THIS_MODULE,
 };
 
index 3e5e860aa38eec64ad8805c6b33c03952d6acad0..ea0af6d81d2b8ac3cdf1d31c5bd5fee61844ab73 100644 (file)
@@ -177,11 +177,11 @@ static ssize_t sca3000_set_ring_int(struct device *dev,
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct sca3000_state *st = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       long val;
+       u8 val;
        int ret;
 
        mutex_lock(&st->lock);
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
@@ -252,7 +252,7 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
        struct iio_buffer *buf;
        struct iio_hw_buffer *ring;
 
-       ring = kzalloc(sizeof *ring, GFP_KERNEL);
+       ring = kzalloc(sizeof(*ring), GFP_KERNEL);
        if (!ring)
                return NULL;
 
@@ -265,7 +265,7 @@ static struct iio_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
        return buf;
 }
 
-static inline void sca3000_rb_free(struct iio_buffer *r)
+static void sca3000_ring_release(struct iio_buffer *r)
 {
        kfree(iio_to_hw_buf(r));
 }
@@ -274,23 +274,28 @@ static const struct iio_buffer_access_funcs sca3000_ring_access_funcs = {
        .read_first_n = &sca3000_read_first_n_hw_rb,
        .get_length = &sca3000_ring_get_length,
        .get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum,
+       .release = sca3000_ring_release,
 };
 
 int sca3000_configure_ring(struct iio_dev *indio_dev)
 {
-       indio_dev->buffer = sca3000_rb_allocate(indio_dev);
-       if (indio_dev->buffer == NULL)
+       struct iio_buffer *buffer;
+
+       buffer = sca3000_rb_allocate(indio_dev);
+       if (buffer == NULL)
                return -ENOMEM;
        indio_dev->modes |= INDIO_BUFFER_HARDWARE;
 
        indio_dev->buffer->access = &sca3000_ring_access_funcs;
 
+       iio_device_attach_buffer(indio_dev, buffer);
+
        return 0;
 }
 
 void sca3000_unconfigure_ring(struct iio_dev *indio_dev)
 {
-       sca3000_rb_free(indio_dev->buffer);
+       iio_buffer_put(indio_dev->buffer);
 }
 
 static inline
index cabc7a367db50833f6e40dc55ebec4efb9cb57bb..1cf476484d7713a4ce744db6664602f6cb4c13fc 100644 (file)
@@ -102,7 +102,7 @@ config AD7280
 
 config LPC32XX_ADC
        tristate "NXP LPC32XX ADC"
-       depends on ARCH_LPC32XX
+       depends on ARCH_LPC32XX || COMPILE_TEST
        help
          Say yes here to build support for the integrated ADC inside the
          LPC32XX SoC. Note that this feature uses the same hardware as the
@@ -113,7 +113,8 @@ config LPC32XX_ADC
 
 config MXS_LRADC
        tristate "Freescale i.MX23/i.MX28 LRADC"
-       depends on ARCH_MXS
+       depends on ARCH_MXS || COMPILE_TEST
+       select STMP_DEVICE
        select IIO_BUFFER
        select IIO_TRIGGERED_BUFFER
        help
@@ -125,7 +126,7 @@ config MXS_LRADC
 
 config SPEAR_ADC
        tristate "ST SPEAr ADC"
-       depends on PLAT_SPEAR
+       depends on PLAT_SPEAR || COMPILE_TEST
        help
          Say yes here to build support for the integrated ADC inside the
          ST SPEAr SoC. Provides direct access via sysfs.
index 3283e282953653eab17c098c8df6bcfe64f9d602..83bb44b381524bc448929ccab8fe29ffad92c496 100644 (file)
@@ -623,17 +623,17 @@ static int ad7192_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
 
        st = iio_priv(indio_dev);
 
-       st->reg = regulator_get(&spi->dev, "vcc");
+       st->reg = devm_regulator_get(&spi->dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
 
                voltage_uv = regulator_get_voltage(st->reg);
        }
@@ -677,11 +677,6 @@ error_remove_trigger:
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-
-       iio_device_free(indio_dev);
 
        return ret;
 }
@@ -694,10 +689,8 @@ static int ad7192_remove(struct spi_device *spi)
        iio_device_unregister(indio_dev);
        ad_sd_cleanup_buffer_and_trigger(indio_dev);
 
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
 
        return 0;
 }
index c19618bc37c4a004e21206e9ae55e5116ad4016e..8209fa542a8a00275103d87585f415d281a69781 100644 (file)
@@ -783,7 +783,6 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad7280_state *st = iio_priv(indio_dev);
-       unsigned int scale_uv;
        int ret;
 
        switch (m) {
@@ -804,13 +803,12 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
                if ((chan->address & 0xFF) <= AD7280A_CELL_VOLTAGE_6)
-                       scale_uv = (4000 * 1000) >> AD7280A_BITS;
+                       *val = 4000;
                else
-                       scale_uv = (5000 * 1000) >> AD7280A_BITS;
+                       *val = 5000;
 
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val2 = AD7280A_BITS;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -835,8 +833,9 @@ static int ad7280_probe(struct spi_device *spi)
        int ret;
        const unsigned short tACQ_ns[4] = {465, 1010, 1460, 1890};
        const unsigned short nAVG[4] = {1, 2, 4, 8};
-       struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+       struct iio_dev *indio_dev;
 
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
 
@@ -860,7 +859,7 @@ static int ad7280_probe(struct spi_device *spi)
 
        ret = ad7280_chain_setup(st);
        if (ret < 0)
-               goto error_free_device;
+               return ret;
 
        st->slave_num = ret;
        st->scan_cnt = (st->slave_num + 1) * AD7280A_NUM_CH;
@@ -891,7 +890,7 @@ static int ad7280_probe(struct spi_device *spi)
 
        ret = ad7280_channel_init(st);
        if (ret < 0)
-               goto error_free_device;
+               return ret;
 
        indio_dev->num_channels = ret;
        indio_dev->channels = st->channels;
@@ -940,9 +939,6 @@ error_free_attr:
 error_free_channels:
        kfree(st->channels);
 
-error_free_device:
-       iio_device_free(indio_dev);
-
        return ret;
 }
 
@@ -960,7 +956,6 @@ static int ad7280_remove(struct spi_device *spi)
 
        kfree(st->channels);
        kfree(st->iio_attr);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index a2e61c2fc8d19a319aa1d29e4bfadc7866d6c3f3..d13f8aeeb62fef53460485f6539fab3dbc1b79d3 100644 (file)
@@ -164,97 +164,14 @@ static irqreturn_t ad7291_event_handler(int irq, void *private)
        return IRQ_HANDLED;
 }
 
-static inline ssize_t ad7291_show_hyst(struct device *dev,
-               struct device_attribute *attr,
-               char *buf)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad7291_chip_info *chip = iio_priv(indio_dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       u16 data;
-       int ret;
-
-       ret = ad7291_i2c_read(chip, this_attr->address, &data);
-       if (ret < 0)
-               return ret;
-
-       return sprintf(buf, "%d\n", data & AD7291_VALUE_MASK);
-}
-
-static inline ssize_t ad7291_set_hyst(struct device *dev,
-                                     struct device_attribute *attr,
-                                     const char *buf,
-                                     size_t len)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad7291_chip_info *chip = iio_priv(indio_dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       u16 data;
-       int ret;
-
-       ret = kstrtou16(buf, 10, &data);
-
-       if (ret < 0)
-               return ret;
-       if (data > AD7291_VALUE_MASK)
-               return -EINVAL;
-
-       ret = ad7291_i2c_write(chip, this_attr->address, data);
-       if (ret < 0)
-               return ret;
-
-       return len;
-}
-
-static IIO_DEVICE_ATTR(in_temp0_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst,
-                      AD7291_HYST(8));
-static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(0));
-static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(1));
-static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(2));
-static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(3));
-static IIO_DEVICE_ATTR(in_voltage4_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(4));
-static IIO_DEVICE_ATTR(in_voltage5_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(5));
-static IIO_DEVICE_ATTR(in_voltage6_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(6));
-static IIO_DEVICE_ATTR(in_voltage7_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad7291_show_hyst, ad7291_set_hyst, AD7291_HYST(7));
-
-static struct attribute *ad7291_event_attributes[] = {
-       &iio_dev_attr_in_temp0_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage4_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage5_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage6_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage7_thresh_both_hyst_raw.dev_attr.attr,
-       NULL,
-};
-
-static unsigned int ad7291_threshold_reg(u64 event_code)
+static unsigned int ad7291_threshold_reg(const struct iio_chan_spec *chan,
+       enum iio_event_direction dir, enum iio_event_info info)
 {
        unsigned int offset;
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_VOLTAGE:
-               offset = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
+               offset = chan->channel;
                break;
        case IIO_TEMP:
                offset = 8;
@@ -263,69 +180,78 @@ static unsigned int ad7291_threshold_reg(u64 event_code)
            return 0;
        }
 
-       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
-               return AD7291_DATA_LOW(offset);
-       else
-               return AD7291_DATA_HIGH(offset);
+       switch (info) {
+       case IIO_EV_INFO_VALUE:
+                       if (dir == IIO_EV_DIR_FALLING)
+                                       return AD7291_DATA_HIGH(offset);
+                       else
+                                       return AD7291_DATA_LOW(offset);
+       case IIO_EV_INFO_HYSTERESIS:
+                       return AD7291_HYST(offset);
+       default:
+                       break;
+       }
+       return 0;
 }
 
 static int ad7291_read_event_value(struct iio_dev *indio_dev,
-                                  u64 event_code,
-                                  int *val)
+                                  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 ad7291_chip_info *chip = iio_priv(indio_dev);
        int ret;
        u16 uval;
 
-       ret = ad7291_i2c_read(chip, ad7291_threshold_reg(event_code), &uval);
+       ret = ad7291_i2c_read(chip, ad7291_threshold_reg(chan, dir, info),
+               &uval);
        if (ret < 0)
                return ret;
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
-       case IIO_VOLTAGE:
+       if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE)
                *val = uval & AD7291_VALUE_MASK;
-               return 0;
-       case IIO_TEMP:
+
+       else
                *val = sign_extend32(uval, 11);
-               return 0;
-       default:
-               return -EINVAL;
-       };
+
+       return IIO_VAL_INT;
 }
 
 static int ad7291_write_event_value(struct iio_dev *indio_dev,
-                                   u64 event_code,
-                                   int val)
+                                   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 ad7291_chip_info *chip = iio_priv(indio_dev);
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
-       case IIO_VOLTAGE:
+       if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE) {
                if (val > AD7291_VALUE_MASK || val < 0)
                        return -EINVAL;
-               break;
-       case IIO_TEMP:
+       } else {
                if (val > 2047 || val < -2048)
                        return -EINVAL;
-               break;
-       default:
-               return -EINVAL;
        }
 
-       return ad7291_i2c_write(chip, ad7291_threshold_reg(event_code), val);
+       return ad7291_i2c_write(chip, ad7291_threshold_reg(chan, dir, info),
+               val);
 }
 
 static int ad7291_read_event_config(struct iio_dev *indio_dev,
-                                   u64 event_code)
+                                   const struct iio_chan_spec *chan,
+                                   enum iio_event_type type,
+                                   enum iio_event_direction dir)
 {
        struct ad7291_chip_info *chip = iio_priv(indio_dev);
        /* To be enabled the channel must simply be on. If any are enabled
           we are in continuous sampling mode */
 
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_VOLTAGE:
-               if (chip->c_mask &
-                   (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))
+               if (chip->c_mask & (1 << (15 - chan->channel)))
                        return 1;
                else
                        return 0;
@@ -339,11 +265,14 @@ static int ad7291_read_event_config(struct iio_dev *indio_dev,
 }
 
 static int ad7291_write_event_config(struct iio_dev *indio_dev,
-                                    u64 event_code,
+                                    const struct iio_chan_spec *chan,
+                                    enum iio_event_type type,
+                                    enum iio_event_direction dir,
                                     int state)
 {
        int ret = 0;
        struct ad7291_chip_info *chip = iio_priv(indio_dev);
+       unsigned int mask;
        u16 regval;
 
        mutex_lock(&chip->state_lock);
@@ -354,16 +283,14 @@ static int ad7291_write_event_config(struct iio_dev *indio_dev,
         * Possible to disable temp as well but that makes single read tricky.
         */
 
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       mask = BIT(15 - chan->channel);
+
+       switch (chan->type) {
        case IIO_VOLTAGE:
-               if ((!state) && (chip->c_mask & (1 << (15 -
-                               IIO_EVENT_CODE_EXTRACT_CHAN(event_code)))))
-                       chip->c_mask &= ~(1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
-                                                       (event_code)));
-               else if (state && (!(chip->c_mask & (1 << (15 -
-                               IIO_EVENT_CODE_EXTRACT_CHAN(event_code))))))
-                       chip->c_mask |= (1 << (15 - IIO_EVENT_CODE_EXTRACT_CHAN
-                                                       (event_code)));
+               if ((!state) && (chip->c_mask & mask))
+                       chip->c_mask &= ~mask;
+               else if (state && (!(chip->c_mask & mask)))
+                       chip->c_mask |= mask;
                else
                        break;
 
@@ -473,6 +400,24 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
        }
 }
 
+static const struct iio_event_spec ad7291_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 AD7291_VOLTAGE_CHAN(_chan)                                     \
 {                                                                      \
        .type = IIO_VOLTAGE,                                            \
@@ -480,8 +425,8 @@ static int ad7291_read_raw(struct iio_dev *indio_dev,
        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),           \
        .indexed = 1,                                                   \
        .channel = _chan,                                               \
-       .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|\
-       IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)              \
+       .event_spec = ad7291_events,                                    \
+       .num_event_specs = ARRAY_SIZE(ad7291_events),                   \
 }
 
 static const struct iio_chan_spec ad7291_channels[] = {
@@ -500,23 +445,17 @@ static const struct iio_chan_spec ad7291_channels[] = {
                                BIT(IIO_CHAN_INFO_SCALE),
                .indexed = 1,
                .channel = 0,
-               .event_mask =
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)|
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)
+               .event_spec = ad7291_events,
+               .num_event_specs = ARRAY_SIZE(ad7291_events),
        }
 };
 
-static struct attribute_group ad7291_event_attribute_group = {
-       .attrs = ad7291_event_attributes,
-};
-
 static const struct iio_info ad7291_info = {
        .read_raw = &ad7291_read_raw,
-       .read_event_config = &ad7291_read_event_config,
-       .write_event_config = &ad7291_write_event_config,
-       .read_event_value = &ad7291_read_event_value,
-       .write_event_value = &ad7291_write_event_value,
-       .event_attrs = &ad7291_event_attribute_group,
+       .read_event_config_new = &ad7291_read_event_config,
+       .write_event_config_new = &ad7291_write_event_config,
+       .read_event_value_new = &ad7291_read_event_value,
+       .write_event_value_new = &ad7291_write_event_value,
        .driver_module = THIS_MODULE,
 };
 
@@ -528,21 +467,19 @@ static int ad7291_probe(struct i2c_client *client,
        struct iio_dev *indio_dev;
        int ret = 0;
 
-       indio_dev = iio_device_alloc(sizeof(*chip));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
+       if (!indio_dev)
+               return -ENOMEM;
        chip = iio_priv(indio_dev);
 
        if (pdata && pdata->use_external_ref) {
-               chip->reg = regulator_get(&client->dev, "vref");
+               chip->reg = devm_regulator_get(&client->dev, "vref");
                if (IS_ERR(chip->reg))
-                       goto error_free;
+                       return ret;
 
                ret = regulator_enable(chip->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
        }
 
        mutex_init(&chip->state_lock);
@@ -601,12 +538,7 @@ error_unreg_irq:
 error_disable_reg:
        if (chip->reg)
                regulator_disable(chip->reg);
-error_put_reg:
-       if (chip->reg)
-               regulator_put(chip->reg);
-error_free:
-       iio_device_free(indio_dev);
-error_ret:
+
        return ret;
 }
 
@@ -620,12 +552,8 @@ static int ad7291_remove(struct i2c_client *client)
        if (client->irq)
                free_irq(client->irq, indio_dev);
 
-       if (chip->reg) {
+       if (chip->reg)
                regulator_disable(chip->reg);
-               regulator_put(chip->reg);
-       }
-
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 72868ceda360cdd969cae70ddc6b1e50b2b33bb6..2083673a79ca676f0460274c160cfc5fb4ca6c4f 100644 (file)
@@ -85,7 +85,6 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
 {
        int ret;
        struct ad7606_state *st = iio_priv(indio_dev);
-       unsigned int scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_RAW:
@@ -101,11 +100,9 @@ static int ad7606_read_raw(struct iio_dev *indio_dev,
                *val = (short) ret;
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->range * 1000 * 2)
-                       >> st->chip_info->channels[0].scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->range * 2;
+               *val2 = st->chip_info->channels[0].scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -425,8 +422,7 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
        struct ad7606_state *st = iio_priv(indio_dev);
 
        if (iio_buffer_enabled(indio_dev)) {
-               if (!work_pending(&st->poll_work))
-                       schedule_work(&st->poll_work);
+               schedule_work(&st->poll_work);
        } else {
                st->done = true;
                wake_up_interruptible(&st->wq_data_avail);
@@ -466,12 +462,11 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
        struct ad7606_platform_data *pdata = dev->platform_data;
        struct ad7606_state *st;
        int ret;
-       struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+       struct iio_dev *indio_dev;
 
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
+       if (!indio_dev)
+               return ERR_PTR(-ENOMEM);
 
        st = iio_priv(indio_dev);
 
@@ -489,11 +484,11 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
                st->oversampling = pdata->default_os;
        }
 
-       st->reg = regulator_get(dev, "vcc");
+       st->reg = devm_regulator_get(dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ERR_PTR(ret);
        }
 
        st->pdata = pdata;
@@ -554,11 +549,6 @@ error_free_gpios:
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-       iio_device_free(indio_dev);
-error_ret:
        return ERR_PTR(ret);
 }
 
@@ -570,13 +560,10 @@ int ad7606_remove(struct iio_dev *indio_dev, int irq)
        ad7606_ring_cleanup(indio_dev);
 
        free_irq(irq, indio_dev);
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
 
        ad7606_free_gpios(st);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 2b25cb07fe41d1470513424380de4ab439657191..3bf174cb19b1ef3573482896fef1848a3f7941ff 100644 (file)
@@ -46,7 +46,6 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
        struct ad7606_state *st = container_of(work_s, struct ad7606_state,
                                                poll_work);
        struct iio_dev *indio_dev = iio_priv_to_dev(st);
-       s64 time_ns;
        __u8 *buf;
        int ret;
 
@@ -78,12 +77,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
                        goto done;
        }
 
-       time_ns = iio_get_time_ns();
-
-       if (indio_dev->scan_timestamp)
-               *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns;
-
-       iio_push_to_buffers(indio_dev, buf);
+       iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns());
 done:
        gpio_set_value(st->pdata->gpio_convst, 0);
        iio_trigger_notify_done(indio_dev->trig);
index e1f88603d7e023f2fe389ceb1af865de43141de9..273add3ed63fd8e80532110a1f793b218175caf0 100644 (file)
@@ -90,17 +90,14 @@ static int ad7780_read_raw(struct iio_dev *indio_dev,
                           long m)
 {
        struct ad7780_state *st = iio_priv(indio_dev);
-       unsigned long scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_RAW:
                return ad_sigma_delta_single_conversion(indio_dev, chan, val);
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->int_vref_mv * 100000 * st->gain)
-                       >> (chan->scan_type.realbits - 1);
-               *val =  scale_uv / 100000;
-               *val2 = (scale_uv % 100000) * 10;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->int_vref_mv * st->gain;
+               *val2 = chan->scan_type.realbits - 1;
+               return IIO_VAL_FRACTIONAL_LOG2;
        case IIO_CHAN_INFO_OFFSET:
                *val -= (1 << (chan->scan_type.realbits - 1));
                return IIO_VAL_INT;
@@ -171,7 +168,7 @@ static int ad7780_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
        int ret, voltage_uv = 0;
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
 
@@ -180,11 +177,11 @@ static int ad7780_probe(struct spi_device *spi)
 
        ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info);
 
-       st->reg = regulator_get(&spi->dev, "vcc");
+       st->reg = devm_regulator_get(&spi->dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
 
                voltage_uv = regulator_get_voltage(st->reg);
        }
@@ -210,8 +207,8 @@ static int ad7780_probe(struct spi_device *spi)
 
        if (pdata && gpio_is_valid(pdata->gpio_pdrst)) {
 
-               ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
-                              "AD7780 /PDRST");
+               ret = devm_gpio_request_one(&spi->dev, pdata->gpio_pdrst,
+                                       GPIOF_OUT_INIT_LOW, "AD7780 /PDRST");
                if (ret) {
                        dev_err(&spi->dev, "failed to request GPIO PDRST\n");
                        goto error_disable_reg;
@@ -223,7 +220,7 @@ static int ad7780_probe(struct spi_device *spi)
 
        ret = ad_sd_setup_buffer_and_trigger(indio_dev);
        if (ret)
-               goto error_free_gpio;
+               goto error_disable_reg;
 
        ret = iio_device_register(indio_dev);
        if (ret)
@@ -233,17 +230,9 @@ static int ad7780_probe(struct spi_device *spi)
 
 error_cleanup_buffer_and_trigger:
        ad_sd_cleanup_buffer_and_trigger(indio_dev);
-error_free_gpio:
-       if (pdata && gpio_is_valid(pdata->gpio_pdrst))
-               gpio_free(pdata->gpio_pdrst);
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-
-       iio_device_free(indio_dev);
 
        return ret;
 }
@@ -256,14 +245,8 @@ static int ad7780_remove(struct spi_device *spi)
        iio_device_unregister(indio_dev);
        ad_sd_cleanup_buffer_and_trigger(indio_dev);
 
-       if (gpio_is_valid(st->powerdown_gpio))
-               gpio_free(st->powerdown_gpio);
-
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 8470036a3378cba40d787f1e45fcb0410bd5d676..9f48e5c74eed85c8f164208d4ddbaf4ed108dfb8 100644 (file)
@@ -356,11 +356,9 @@ static int ad7816_probe(struct spi_device *spi_dev)
                return -EINVAL;
        }
 
-       indio_dev = iio_device_alloc(sizeof(*chip));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip));
+       if (!indio_dev)
+               return -ENOMEM;
        chip = iio_priv(indio_dev);
        /* this is only used for device removal purposes */
        dev_set_drvdata(&spi_dev->dev, indio_dev);
@@ -372,25 +370,28 @@ static int ad7816_probe(struct spi_device *spi_dev)
        chip->convert_pin = pins[1];
        chip->busy_pin = pins[2];
 
-       ret = gpio_request(chip->rdwr_pin, spi_get_device_id(spi_dev)->name);
+       ret = devm_gpio_request(&spi_dev->dev, chip->rdwr_pin,
+                                       spi_get_device_id(spi_dev)->name);
        if (ret) {
                dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n",
                        chip->rdwr_pin);
-               goto error_free_device;
+               return ret;
        }
        gpio_direction_input(chip->rdwr_pin);
-       ret = gpio_request(chip->convert_pin, spi_get_device_id(spi_dev)->name);
+       ret = devm_gpio_request(&spi_dev->dev, chip->convert_pin,
+                                       spi_get_device_id(spi_dev)->name);
        if (ret) {
                dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n",
                        chip->convert_pin);
-               goto error_free_gpio_rdwr;
+               return ret;
        }
        gpio_direction_input(chip->convert_pin);
-       ret = gpio_request(chip->busy_pin, spi_get_device_id(spi_dev)->name);
+       ret = devm_gpio_request(&spi_dev->dev, chip->busy_pin,
+                                       spi_get_device_id(spi_dev)->name);
        if (ret) {
                dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
                        chip->busy_pin);
-               goto error_free_gpio_convert;
+               return ret;
        }
        gpio_direction_input(chip->busy_pin);
 
@@ -401,51 +402,31 @@ static int ad7816_probe(struct spi_device *spi_dev)
 
        if (spi_dev->irq) {
                /* Only low trigger is supported in ad7816/7/8 */
-               ret = request_threaded_irq(spi_dev->irq,
-                                          NULL,
-                                          &ad7816_event_handler,
-                                          IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-                                          indio_dev->name,
-                                          indio_dev);
+               ret = devm_request_threaded_irq(&spi_dev->dev, spi_dev->irq,
+                                               NULL,
+                                               &ad7816_event_handler,
+                                               IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+                                               indio_dev->name,
+                                               indio_dev);
                if (ret)
-                       goto error_free_gpio;
+                       return ret;
        }
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_irq;
+               return ret;
 
        dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
                         indio_dev->name);
 
        return 0;
-error_free_irq:
-       free_irq(spi_dev->irq, indio_dev);
-error_free_gpio:
-       gpio_free(chip->busy_pin);
-error_free_gpio_convert:
-       gpio_free(chip->convert_pin);
-error_free_gpio_rdwr:
-       gpio_free(chip->rdwr_pin);
-error_free_device:
-       iio_device_free(indio_dev);
-error_ret:
-       return ret;
 }
 
 static int ad7816_remove(struct spi_device *spi_dev)
 {
        struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev);
-       struct ad7816_chip_info *chip = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       dev_set_drvdata(&spi_dev->dev, NULL);
-       if (spi_dev->irq)
-               free_irq(spi_dev->irq, indio_dev);
-       gpio_free(chip->busy_pin);
-       gpio_free(chip->convert_pin);
-       gpio_free(chip->rdwr_pin);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index b51680c1c331a65593a531a93ec6f1bd6f1b191c..a591aa6feae142dc0eaa3507e8f5ad0279396ab7 100644 (file)
 #define AD7998_ALERT_STAT_REG                  0x1
 #define AD7998_CONF_REG                                0x2
 #define AD7998_CYCLE_TMR_REG                   0x3
-#define AD7998_DATALOW_CH1_REG                 0x4
-#define AD7998_DATAHIGH_CH1_REG                        0x5
-#define AD7998_HYST_CH1_REG                    0x6
-#define AD7998_DATALOW_CH2_REG                 0x7
-#define AD7998_DATAHIGH_CH2_REG                        0x8
-#define AD7998_HYST_CH2_REG                    0x9
-#define AD7998_DATALOW_CH3_REG                 0xA
-#define AD7998_DATAHIGH_CH3_REG                        0xB
-#define AD7998_HYST_CH3_REG                    0xC
-#define AD7998_DATALOW_CH4_REG                 0xD
-#define AD7998_DATAHIGH_CH4_REG                        0xE
-#define AD7998_HYST_CH4_REG                    0xF
+
+#define AD7998_DATALOW_REG(x)                  ((x) * 3 + 0x4)
+#define AD7998_DATAHIGH_REG(x)                 ((x) * 3 + 0x5)
+#define AD7998_HYST_REG(x)                     ((x) * 3 + 0x6)
 
 #define AD7998_CYC_MASK                                0x7
 #define AD7998_CYC_DIS                         0x0
index 2b2049c8bc6ba969896168f6b22b58ed7336afcc..9428be82b655f0d6456e5d4c0dec3d0d6661dcc2 100644 (file)
@@ -163,7 +163,6 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
 {
        int ret;
        struct ad799x_state *st = iio_priv(indio_dev);
-       unsigned int scale_uv;
 
        switch (m) {
        case IIO_CHAN_INFO_RAW:
@@ -180,10 +179,9 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
                        RES_MASK(chan->scan_type.realbits);
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_SCALE:
-               scale_uv = (st->int_vref_mv * 1000) >> chan->scan_type.realbits;
-               *val =  scale_uv / 1000;
-               *val2 = (scale_uv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = st->int_vref_mv;
+               *val2 = chan->scan_type.realbits;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
        return -EINVAL;
 }
@@ -254,98 +252,70 @@ error_ret_mutex:
 }
 
 static int ad799x_read_event_config(struct iio_dev *indio_dev,
-                                   u64 event_code)
+                                   const struct iio_chan_spec *chan,
+                                   enum iio_event_type type,
+                                   enum iio_event_direction dir)
 {
        return 1;
 }
 
-static const u8 ad799x_threshold_addresses[][2] = {
-       { AD7998_DATALOW_CH1_REG, AD7998_DATAHIGH_CH1_REG },
-       { AD7998_DATALOW_CH2_REG, AD7998_DATAHIGH_CH2_REG },
-       { AD7998_DATALOW_CH3_REG, AD7998_DATAHIGH_CH3_REG },
-       { AD7998_DATALOW_CH4_REG, AD7998_DATAHIGH_CH4_REG },
-};
+static unsigned int ad799x_threshold_reg(const struct iio_chan_spec *chan,
+                                        enum iio_event_direction dir,
+                                        enum iio_event_info info)
+{
+       switch (info) {
+       case IIO_EV_INFO_VALUE:
+               if (dir == IIO_EV_DIR_FALLING)
+                       return AD7998_DATALOW_REG(chan->channel);
+               else
+                       return AD7998_DATAHIGH_REG(chan->channel);
+       case IIO_EV_INFO_HYSTERESIS:
+               return AD7998_HYST_REG(chan->channel);
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
 
 static int ad799x_write_event_value(struct iio_dev *indio_dev,
-                                   u64 event_code,
-                                   int val)
+                                   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)
 {
        int ret;
        struct ad799x_state *st = iio_priv(indio_dev);
-       int direction = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                          IIO_EV_DIR_FALLING);
-       int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
 
        mutex_lock(&indio_dev->mlock);
-       ret = ad799x_i2c_write16(st,
-                                ad799x_threshold_addresses[number][direction],
-                                val);
+       ret = ad799x_i2c_write16(st, ad799x_threshold_reg(chan, dir, info),
+               val);
        mutex_unlock(&indio_dev->mlock);
 
        return ret;
 }
 
 static int ad799x_read_event_value(struct iio_dev *indio_dev,
-                                   u64 event_code,
-                                   int *val)
+                                   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)
 {
        int ret;
        struct ad799x_state *st = iio_priv(indio_dev);
-       int direction = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                          IIO_EV_DIR_FALLING);
-       int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
        u16 valin;
 
        mutex_lock(&indio_dev->mlock);
-       ret = ad799x_i2c_read16(st,
-                               ad799x_threshold_addresses[number][direction],
-                               &valin);
+       ret = ad799x_i2c_read16(st, ad799x_threshold_reg(chan, dir, info),
+               &valin);
        mutex_unlock(&indio_dev->mlock);
        if (ret < 0)
                return ret;
        *val = valin;
 
-       return 0;
-}
-
-static ssize_t ad799x_read_channel_config(struct device *dev,
-                                       struct device_attribute *attr,
-                                       char *buf)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad799x_state *st = iio_priv(indio_dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-       int ret;
-       u16 val;
-       ret = ad799x_i2c_read16(st, this_attr->address, &val);
-       if (ret)
-               return ret;
-
-       return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t ad799x_write_channel_config(struct device *dev,
-                                        struct device_attribute *attr,
-                                        const char *buf,
-                                        size_t len)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct ad799x_state *st = iio_priv(indio_dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-       long val;
-       int ret;
-
-       ret = kstrtol(buf, 10, &val);
-       if (ret)
-               return ret;
-
-       mutex_lock(&indio_dev->mlock);
-       ret = ad799x_i2c_write16(st, this_attr->address, val);
-       mutex_unlock(&indio_dev->mlock);
-
-       return ret ? ret : len;
+       return IIO_VAL_INT;
 }
 
 static irqreturn_t ad799x_event_handler(int irq, void *private)
@@ -383,60 +353,19 @@ done:
        return IRQ_HANDLED;
 }
 
-static IIO_DEVICE_ATTR(in_voltage0_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad799x_read_channel_config,
-                      ad799x_write_channel_config,
-                      AD7998_HYST_CH1_REG);
-
-static IIO_DEVICE_ATTR(in_voltage1_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad799x_read_channel_config,
-                      ad799x_write_channel_config,
-                      AD7998_HYST_CH2_REG);
-
-static IIO_DEVICE_ATTR(in_voltage2_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad799x_read_channel_config,
-                      ad799x_write_channel_config,
-                      AD7998_HYST_CH3_REG);
-
-static IIO_DEVICE_ATTR(in_voltage3_thresh_both_hyst_raw,
-                      S_IRUGO | S_IWUSR,
-                      ad799x_read_channel_config,
-                      ad799x_write_channel_config,
-                      AD7998_HYST_CH4_REG);
-
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
                              ad799x_read_frequency,
                              ad799x_write_frequency);
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("15625 7812 3906 1953 976 488 244 0");
 
-static struct attribute *ad7993_4_7_8_event_attributes[] = {
-       &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage2_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage3_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_sampling_frequency.dev_attr.attr,
-       &iio_const_attr_sampling_frequency_available.dev_attr.attr,
-       NULL,
-};
-
-static struct attribute_group ad7993_4_7_8_event_attrs_group = {
-       .attrs = ad7993_4_7_8_event_attributes,
-       .name = "events",
-};
-
-static struct attribute *ad7992_event_attributes[] = {
-       &iio_dev_attr_in_voltage0_thresh_both_hyst_raw.dev_attr.attr,
-       &iio_dev_attr_in_voltage1_thresh_both_hyst_raw.dev_attr.attr,
+static struct attribute *ad799x_event_attributes[] = {
        &iio_dev_attr_sampling_frequency.dev_attr.attr,
        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
        NULL,
 };
 
-static struct attribute_group ad7992_event_attrs_group = {
-       .attrs = ad7992_event_attributes,
+static struct attribute_group ad799x_event_attrs_group = {
+       .attrs = ad799x_event_attributes,
        .name = "events",
 };
 
@@ -445,29 +374,35 @@ static const struct iio_info ad7991_info = {
        .driver_module = THIS_MODULE,
 };
 
-static const struct iio_info ad7992_info = {
-       .read_raw = &ad799x_read_raw,
-       .event_attrs = &ad7992_event_attrs_group,
-       .read_event_config = &ad799x_read_event_config,
-       .read_event_value = &ad799x_read_event_value,
-       .write_event_value = &ad799x_write_event_value,
-       .driver_module = THIS_MODULE,
-};
-
 static const struct iio_info ad7993_4_7_8_info = {
        .read_raw = &ad799x_read_raw,
-       .event_attrs = &ad7993_4_7_8_event_attrs_group,
-       .read_event_config = &ad799x_read_event_config,
-       .read_event_value = &ad799x_read_event_value,
-       .write_event_value = &ad799x_write_event_value,
+       .event_attrs = &ad799x_event_attrs_group,
+       .read_event_config_new = &ad799x_read_event_config,
+       .read_event_value_new = &ad799x_read_event_value,
+       .write_event_value_new = &ad799x_write_event_value,
        .driver_module = THIS_MODULE,
        .update_scan_mode = ad7997_8_update_scan_mode,
 };
 
-#define AD799X_EV_MASK (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
-                       IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+static const struct iio_event_spec ad799x_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 AD799X_CHANNEL(_index, _realbits, _evmask) { \
+#define _AD799X_CHANNEL(_index, _realbits, _ev_spec, _num_ev_spec) { \
        .type = IIO_VOLTAGE, \
        .indexed = 1, \
        .channel = (_index), \
@@ -475,16 +410,24 @@ static const struct iio_info ad7993_4_7_8_info = {
        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
        .scan_index = (_index), \
        .scan_type = IIO_ST('u', _realbits, 16, 12 - (_realbits)), \
-       .event_mask = (_evmask), \
+       .event_spec = _ev_spec, \
+       .num_event_specs = _num_ev_spec, \
 }
 
+#define AD799X_CHANNEL(_index, _realbits) \
+       _AD799X_CHANNEL(_index, _realbits, NULL, 0)
+
+#define AD799X_CHANNEL_WITH_EVENTS(_index, _realbits) \
+       _AD799X_CHANNEL(_index, _realbits, ad799x_events, \
+               ARRAY_SIZE(ad799x_events))
+
 static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        [ad7991] = {
                .channel = {
-                       AD799X_CHANNEL(0, 12, 0),
-                       AD799X_CHANNEL(1, 12, 0),
-                       AD799X_CHANNEL(2, 12, 0),
-                       AD799X_CHANNEL(3, 12, 0),
+                       AD799X_CHANNEL(0, 12),
+                       AD799X_CHANNEL(1, 12),
+                       AD799X_CHANNEL(2, 12),
+                       AD799X_CHANNEL(3, 12),
                        IIO_CHAN_SOFT_TIMESTAMP(4),
                },
                .num_channels = 5,
@@ -492,10 +435,10 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7995] = {
                .channel = {
-                       AD799X_CHANNEL(0, 10, 0),
-                       AD799X_CHANNEL(1, 10, 0),
-                       AD799X_CHANNEL(2, 10, 0),
-                       AD799X_CHANNEL(3, 10, 0),
+                       AD799X_CHANNEL(0, 10),
+                       AD799X_CHANNEL(1, 10),
+                       AD799X_CHANNEL(2, 10),
+                       AD799X_CHANNEL(3, 10),
                        IIO_CHAN_SOFT_TIMESTAMP(4),
                },
                .num_channels = 5,
@@ -503,10 +446,10 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7999] = {
                .channel = {
-                       AD799X_CHANNEL(0, 8, 0),
-                       AD799X_CHANNEL(1, 8, 0),
-                       AD799X_CHANNEL(2, 8, 0),
-                       AD799X_CHANNEL(3, 8, 0),
+                       AD799X_CHANNEL(0, 8),
+                       AD799X_CHANNEL(1, 8),
+                       AD799X_CHANNEL(2, 8),
+                       AD799X_CHANNEL(3, 8),
                        IIO_CHAN_SOFT_TIMESTAMP(4),
                },
                .num_channels = 5,
@@ -514,20 +457,20 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7992] = {
                .channel = {
-                       AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
+                       AD799X_CHANNEL_WITH_EVENTS(0, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(1, 12),
                        IIO_CHAN_SOFT_TIMESTAMP(3),
                },
                .num_channels = 3,
                .default_config = AD7998_ALERT_EN,
-               .info = &ad7992_info,
+               .info = &ad7993_4_7_8_info,
        },
        [ad7993] = {
                .channel = {
-                       AD799X_CHANNEL(0, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(1, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(2, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(3, 10, AD799X_EV_MASK),
+                       AD799X_CHANNEL_WITH_EVENTS(0, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(1, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(2, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(3, 10),
                        IIO_CHAN_SOFT_TIMESTAMP(4),
                },
                .num_channels = 5,
@@ -536,10 +479,10 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7994] = {
                .channel = {
-                       AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(2, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(3, 12, AD799X_EV_MASK),
+                       AD799X_CHANNEL_WITH_EVENTS(0, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(1, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(2, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(3, 12),
                        IIO_CHAN_SOFT_TIMESTAMP(4),
                },
                .num_channels = 5,
@@ -548,14 +491,14 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7997] = {
                .channel = {
-                       AD799X_CHANNEL(0, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(1, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(2, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(3, 10, AD799X_EV_MASK),
-                       AD799X_CHANNEL(4, 10, 0),
-                       AD799X_CHANNEL(5, 10, 0),
-                       AD799X_CHANNEL(6, 10, 0),
-                       AD799X_CHANNEL(7, 10, 0),
+                       AD799X_CHANNEL_WITH_EVENTS(0, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(1, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(2, 10),
+                       AD799X_CHANNEL_WITH_EVENTS(3, 10),
+                       AD799X_CHANNEL(4, 10),
+                       AD799X_CHANNEL(5, 10),
+                       AD799X_CHANNEL(6, 10),
+                       AD799X_CHANNEL(7, 10),
                        IIO_CHAN_SOFT_TIMESTAMP(8),
                },
                .num_channels = 9,
@@ -564,14 +507,14 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
        },
        [ad7998] = {
                .channel = {
-                       AD799X_CHANNEL(0, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(1, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(2, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(3, 12, AD799X_EV_MASK),
-                       AD799X_CHANNEL(4, 12, 0),
-                       AD799X_CHANNEL(5, 12, 0),
-                       AD799X_CHANNEL(6, 12, 0),
-                       AD799X_CHANNEL(7, 12, 0),
+                       AD799X_CHANNEL_WITH_EVENTS(0, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(1, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(2, 12),
+                       AD799X_CHANNEL_WITH_EVENTS(3, 12),
+                       AD799X_CHANNEL(4, 12),
+                       AD799X_CHANNEL(5, 12),
+                       AD799X_CHANNEL(6, 12),
+                       AD799X_CHANNEL(7, 12),
                        IIO_CHAN_SOFT_TIMESTAMP(8),
                },
                .num_channels = 9,
@@ -586,8 +529,9 @@ static int ad799x_probe(struct i2c_client *client,
        int ret;
        struct ad799x_platform_data *pdata = client->dev.platform_data;
        struct ad799x_state *st;
-       struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+       struct iio_dev *indio_dev;
 
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
 
@@ -606,11 +550,11 @@ static int ad799x_probe(struct i2c_client *client,
 
        st->int_vref_mv = pdata->vref_mv;
 
-       st->reg = regulator_get(&client->dev, "vcc");
+       st->reg = devm_regulator_get(&client->dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
        }
        st->client = client;
 
@@ -650,10 +594,6 @@ error_cleanup_ring:
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-       iio_device_free(indio_dev);
 
        return ret;
 }
@@ -668,12 +608,9 @@ static int ad799x_remove(struct i2c_client *client)
                free_irq(client->irq, indio_dev);
 
        ad799x_ring_cleanup(indio_dev);
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
        kfree(st->rx_buf);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index c2ebae12ee1961852e83f73a818860d7b8af7550..0ff6c03a483ec0bd72909c0eb49228baf2f555c7 100644 (file)
@@ -35,7 +35,6 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
        struct iio_poll_func *pf = p;
        struct iio_dev *indio_dev = pf->indio_dev;
        struct ad799x_state *st = iio_priv(indio_dev);
-       s64 time_ns;
        int b_sent;
        u8 cmd;
 
@@ -65,13 +64,8 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
        if (b_sent < 0)
                goto out;
 
-       time_ns = iio_get_time_ns();
-
-       if (indio_dev->scan_timestamp)
-               memcpy(st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
-                       &time_ns, sizeof(time_ns));
-
-       iio_push_to_buffers(indio_dev, st->rx_buf);
+       iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
+                       iio_get_time_ns());
 out:
        iio_trigger_notify_done(indio_dev->trig);
 
index 9a4bb0999b51244d3e621610aa626477f5f851f5..ef0a21d8ce15ce76ea4ae39bb72d0523f3bfc230 100644 (file)
@@ -137,43 +137,39 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_err(&pdev->dev, "failed to get platform I/O memory\n");
-               retval = -EBUSY;
-               goto errout1;
+               return -EBUSY;
        }
 
-       iodev = iio_device_alloc(sizeof(struct lpc32xx_adc_info));
-       if (!iodev) {
-               dev_err(&pdev->dev, "failed allocating iio device\n");
-               retval = -ENOMEM;
-               goto errout1;
-       }
+       iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
+       if (!iodev)
+               return -ENOMEM;
 
        info = iio_priv(iodev);
 
-       info->adc_base = ioremap(res->start, resource_size(res));
+       info->adc_base = devm_ioremap(&pdev->dev, res->start,
+                                               resource_size(res));
        if (!info->adc_base) {
                dev_err(&pdev->dev, "failed mapping memory\n");
-               retval = -EBUSY;
-               goto errout2;
+               return -EBUSY;
        }
 
-       info->clk = clk_get(&pdev->dev, NULL);
+       info->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(info->clk)) {
                dev_err(&pdev->dev, "failed getting clock\n");
-               goto errout3;
+               return PTR_ERR(info->clk);
        }
 
        irq = platform_get_irq(pdev, 0);
-       if ((irq < 0) || (irq >= NR_IRQS)) {
+       if (irq <= 0) {
                dev_err(&pdev->dev, "failed getting interrupt resource\n");
-               retval = -EINVAL;
-               goto errout4;
+               return -EINVAL;
        }
 
-       retval = request_irq(irq, lpc32xx_adc_isr, 0, MOD_NAME, info);
+       retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
+                                                               MOD_NAME, info);
        if (retval < 0) {
                dev_err(&pdev->dev, "failed requesting interrupt\n");
-               goto errout4;
+               return retval;
        }
 
        platform_set_drvdata(pdev, iodev);
@@ -189,35 +185,18 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
 
        retval = iio_device_register(iodev);
        if (retval)
-               goto errout5;
+               return retval;
 
        dev_info(&pdev->dev, "LPC32XX ADC driver loaded, IRQ %d\n", irq);
 
        return 0;
-
-errout5:
-       free_irq(irq, info);
-errout4:
-       clk_put(info->clk);
-errout3:
-       iounmap(info->adc_base);
-errout2:
-       iio_device_free(iodev);
-errout1:
-       return retval;
 }
 
 static int lpc32xx_adc_remove(struct platform_device *pdev)
 {
        struct iio_dev *iodev = platform_get_drvdata(pdev);
-       struct lpc32xx_adc_info *info = iio_priv(iodev);
-       int irq = platform_get_irq(pdev, 0);
 
        iio_device_unregister(iodev);
-       free_irq(irq, info);
-       clk_put(info->clk);
-       iounmap(info->adc_base);
-       iio_device_free(iodev);
 
        return 0;
 }
index a08c1736458b4f2cfab9af87c408a65e430d8020..1bb03e196aa75e550d076423b74e845f79905bd6 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/input.h>
+#include <linux/clk.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/buffer.h>
@@ -129,11 +130,24 @@ enum mxs_lradc_ts {
        MXS_LRADC_TOUCHSCREEN_5WIRE,
 };
 
+/*
+ * Touchscreen handling
+ */
+enum lradc_ts_plate {
+       LRADC_TOUCH = 0,
+       LRADC_SAMPLE_X,
+       LRADC_SAMPLE_Y,
+       LRADC_SAMPLE_PRESSURE,
+       LRADC_SAMPLE_VALID,
+};
+
 struct mxs_lradc {
        struct device           *dev;
        void __iomem            *base;
        int                     irq[13];
 
+       struct clk              *clk;
+
        uint32_t                *buffer;
        struct iio_trigger      *trig;
 
@@ -169,32 +183,63 @@ struct mxs_lradc {
 #define CHAN_MASK_TOUCHSCREEN_4WIRE    (0xf << 2)
 #define CHAN_MASK_TOUCHSCREEN_5WIRE    (0x1f << 2)
        enum mxs_lradc_ts       use_touchscreen;
-       bool                    stop_touchscreen;
        bool                    use_touchbutton;
 
        struct input_dev        *ts_input;
-       struct work_struct      ts_work;
+
+       enum mxs_lradc_id       soc;
+       enum lradc_ts_plate     cur_plate; /* statemachine */
+       bool                    ts_valid;
+       unsigned                ts_x_pos;
+       unsigned                ts_y_pos;
+       unsigned                ts_pressure;
+
+       /* handle touchscreen's physical behaviour */
+       /* samples per coordinate */
+       unsigned                over_sample_cnt;
+       /* time clocks between samples */
+       unsigned                over_sample_delay;
+       /* time in clocks to wait after the plates where switched */
+       unsigned                settling_delay;
 };
 
 #define        LRADC_CTRL0                             0x00
-#define        LRADC_CTRL0_TOUCH_DETECT_ENABLE         (1 << 23)
-#define        LRADC_CTRL0_TOUCH_SCREEN_TYPE           (1 << 22)
-#define        LRADC_CTRL0_YNNSW       /* YM */        (1 << 21)
-#define        LRADC_CTRL0_YPNSW       /* YP */        (1 << 20)
-#define        LRADC_CTRL0_YPPSW       /* YP */        (1 << 19)
-#define        LRADC_CTRL0_XNNSW       /* XM */        (1 << 18)
-#define        LRADC_CTRL0_XNPSW       /* XM */        (1 << 17)
-#define        LRADC_CTRL0_XPPSW       /* XP */        (1 << 16)
-#define        LRADC_CTRL0_PLATE_MASK                  (0x3f << 16)
+# define LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE  (1 << 23)
+# define LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE    (1 << 22)
+# define LRADC_CTRL0_MX28_YNNSW        /* YM */        (1 << 21)
+# define LRADC_CTRL0_MX28_YPNSW        /* YP */        (1 << 20)
+# define LRADC_CTRL0_MX28_YPPSW        /* YP */        (1 << 19)
+# define LRADC_CTRL0_MX28_XNNSW        /* XM */        (1 << 18)
+# define LRADC_CTRL0_MX28_XNPSW        /* XM */        (1 << 17)
+# define LRADC_CTRL0_MX28_XPPSW        /* XP */        (1 << 16)
+
+# define LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE  (1 << 20)
+# define LRADC_CTRL0_MX23_YM                   (1 << 19)
+# define LRADC_CTRL0_MX23_XM                   (1 << 18)
+# define LRADC_CTRL0_MX23_YP                   (1 << 17)
+# define LRADC_CTRL0_MX23_XP                   (1 << 16)
+
+# define LRADC_CTRL0_MX28_PLATE_MASK \
+               (LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE | \
+               LRADC_CTRL0_MX28_YNNSW | LRADC_CTRL0_MX28_YPNSW | \
+               LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW | \
+               LRADC_CTRL0_MX28_XNPSW | LRADC_CTRL0_MX28_XPPSW)
+
+# define LRADC_CTRL0_MX23_PLATE_MASK \
+               (LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE | \
+               LRADC_CTRL0_MX23_YM | LRADC_CTRL0_MX23_XM | \
+               LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XP)
 
 #define        LRADC_CTRL1                             0x10
 #define        LRADC_CTRL1_TOUCH_DETECT_IRQ_EN         (1 << 24)
 #define        LRADC_CTRL1_LRADC_IRQ_EN(n)             (1 << ((n) + 16))
-#define        LRADC_CTRL1_LRADC_IRQ_EN_MASK           (0x1fff << 16)
+#define        LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK      (0x1fff << 16)
+#define        LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK      (0x01ff << 16)
 #define        LRADC_CTRL1_LRADC_IRQ_EN_OFFSET         16
 #define        LRADC_CTRL1_TOUCH_DETECT_IRQ            (1 << 8)
 #define        LRADC_CTRL1_LRADC_IRQ(n)                (1 << (n))
-#define        LRADC_CTRL1_LRADC_IRQ_MASK              0x1fff
+#define        LRADC_CTRL1_MX28_LRADC_IRQ_MASK         0x1fff
+#define        LRADC_CTRL1_MX23_LRADC_IRQ_MASK         0x01ff
 #define        LRADC_CTRL1_LRADC_IRQ_OFFSET            0
 
 #define        LRADC_CTRL2                             0x20
@@ -207,19 +252,33 @@ struct mxs_lradc {
 #define        LRADC_CH_ACCUMULATE                     (1 << 29)
 #define        LRADC_CH_NUM_SAMPLES_MASK               (0x1f << 24)
 #define        LRADC_CH_NUM_SAMPLES_OFFSET             24
+#define        LRADC_CH_NUM_SAMPLES(x) \
+                               ((x) << LRADC_CH_NUM_SAMPLES_OFFSET)
 #define        LRADC_CH_VALUE_MASK                     0x3ffff
 #define        LRADC_CH_VALUE_OFFSET                   0
 
 #define        LRADC_DELAY(n)                          (0xd0 + (0x10 * (n)))
 #define        LRADC_DELAY_TRIGGER_LRADCS_MASK         (0xff << 24)
 #define        LRADC_DELAY_TRIGGER_LRADCS_OFFSET       24
+#define        LRADC_DELAY_TRIGGER(x) \
+                               (((x) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) & \
+                               LRADC_DELAY_TRIGGER_LRADCS_MASK)
 #define        LRADC_DELAY_KICK                        (1 << 20)
 #define        LRADC_DELAY_TRIGGER_DELAYS_MASK         (0xf << 16)
 #define        LRADC_DELAY_TRIGGER_DELAYS_OFFSET       16
+#define        LRADC_DELAY_TRIGGER_DELAYS(x) \
+                               (((x) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) & \
+                               LRADC_DELAY_TRIGGER_DELAYS_MASK)
 #define        LRADC_DELAY_LOOP_COUNT_MASK             (0x1f << 11)
 #define        LRADC_DELAY_LOOP_COUNT_OFFSET           11
+#define        LRADC_DELAY_LOOP(x) \
+                               (((x) << LRADC_DELAY_LOOP_COUNT_OFFSET) & \
+                               LRADC_DELAY_LOOP_COUNT_MASK)
 #define        LRADC_DELAY_DELAY_MASK                  0x7ff
 #define        LRADC_DELAY_DELAY_OFFSET                0
+#define        LRADC_DELAY_DELAY(x) \
+                               (((x) << LRADC_DELAY_DELAY_OFFSET) & \
+                               LRADC_DELAY_DELAY_MASK)
 
 #define        LRADC_CTRL4                             0x140
 #define        LRADC_CTRL4_LRADCSELECT_MASK(n)         (0xf << ((n) * 4))
@@ -228,6 +287,475 @@ struct mxs_lradc {
 #define LRADC_RESOLUTION                       12
 #define LRADC_SINGLE_SAMPLE_MASK               ((1 << LRADC_RESOLUTION) - 1)
 
+static void mxs_lradc_reg_set(struct mxs_lradc *lradc, u32 val, u32 reg)
+{
+       writel(val, lradc->base + reg + STMP_OFFSET_REG_SET);
+}
+
+static void mxs_lradc_reg_clear(struct mxs_lradc *lradc, u32 val, u32 reg)
+{
+       writel(val, lradc->base + reg + STMP_OFFSET_REG_CLR);
+}
+
+static void mxs_lradc_reg_wrt(struct mxs_lradc *lradc, u32 val, u32 reg)
+{
+       writel(val, lradc->base + reg);
+}
+
+static u32 mxs_lradc_plate_mask(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL0_MX23_PLATE_MASK;
+       else
+               return LRADC_CTRL0_MX28_PLATE_MASK;
+}
+
+static u32 mxs_lradc_irq_en_mask(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL1_MX23_LRADC_IRQ_EN_MASK;
+       else
+               return LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK;
+}
+
+static u32 mxs_lradc_irq_mask(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL1_MX23_LRADC_IRQ_MASK;
+       else
+               return LRADC_CTRL1_MX28_LRADC_IRQ_MASK;
+}
+
+static u32 mxs_lradc_touch_detect_bit(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL0_MX23_TOUCH_DETECT_ENABLE;
+       else
+               return LRADC_CTRL0_MX28_TOUCH_DETECT_ENABLE;
+}
+
+static u32 mxs_lradc_drive_x_plate(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL0_MX23_XP | LRADC_CTRL0_MX23_XM;
+       else
+               return LRADC_CTRL0_MX28_XPPSW | LRADC_CTRL0_MX28_XNNSW;
+}
+
+static u32 mxs_lradc_drive_y_plate(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_YM;
+       else
+               return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_YNNSW;
+}
+
+static u32 mxs_lradc_drive_pressure(struct mxs_lradc *lradc)
+{
+       if (lradc->soc == IMX23_LRADC)
+               return LRADC_CTRL0_MX23_YP | LRADC_CTRL0_MX23_XM;
+       else
+               return LRADC_CTRL0_MX28_YPPSW | LRADC_CTRL0_MX28_XNNSW;
+}
+
+static bool mxs_lradc_check_touch_event(struct mxs_lradc *lradc)
+{
+       return !!(readl(lradc->base + LRADC_STATUS) &
+                                       LRADC_STATUS_TOUCH_DETECT_RAW);
+}
+
+static void mxs_lradc_setup_ts_channel(struct mxs_lradc *lradc, unsigned ch)
+{
+       /*
+        * prepare for oversampling conversion
+        *
+        * from the datasheet:
+        * "The ACCUMULATE bit in the appropriate channel register
+        * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
+        * otherwise, the IRQs will not fire."
+        */
+       mxs_lradc_reg_wrt(lradc, LRADC_CH_ACCUMULATE |
+                       LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1),
+                       LRADC_CH(ch));
+
+       /* from the datasheet:
+        * "Software must clear this register in preparation for a
+        * multi-cycle accumulation.
+        */
+       mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch));
+
+       /* prepare the delay/loop unit according to the oversampling count */
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch) |
+               LRADC_DELAY_TRIGGER_DELAYS(0) |
+               LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
+               LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
+                       LRADC_DELAY(3));
+
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
+                       LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
+                       LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
+
+       /* wake us again, when the complete conversion is done */
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch), LRADC_CTRL1);
+       /*
+        * after changing the touchscreen plates setting
+        * the signals need some initial time to settle. Start the
+        * SoC's delay unit and start the conversion later
+        * and automatically.
+        */
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
+               LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */
+               LRADC_DELAY_KICK |
+               LRADC_DELAY_DELAY(lradc->settling_delay),
+                       LRADC_DELAY(2));
+}
+
+/*
+ * Pressure detection is special:
+ * We want to do both required measurements for the pressure detection in
+ * one turn. Use the hardware features to chain both conversions and let the
+ * hardware report one interrupt if both conversions are done
+ */
+static void mxs_lradc_setup_ts_pressure(struct mxs_lradc *lradc, unsigned ch1,
+                                                       unsigned ch2)
+{
+       u32 reg;
+
+       /*
+        * prepare for oversampling conversion
+        *
+        * from the datasheet:
+        * "The ACCUMULATE bit in the appropriate channel register
+        * HW_LRADC_CHn must be set to 1 if NUM_SAMPLES is greater then 0;
+        * otherwise, the IRQs will not fire."
+        */
+       reg = LRADC_CH_ACCUMULATE |
+               LRADC_CH_NUM_SAMPLES(lradc->over_sample_cnt - 1);
+       mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch1));
+       mxs_lradc_reg_wrt(lradc, reg, LRADC_CH(ch2));
+
+       /* from the datasheet:
+        * "Software must clear this register in preparation for a
+        * multi-cycle accumulation.
+        */
+       mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch1));
+       mxs_lradc_reg_clear(lradc, LRADC_CH_VALUE_MASK, LRADC_CH(ch2));
+
+       /* prepare the delay/loop unit according to the oversampling count */
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << ch1) |
+               LRADC_DELAY_TRIGGER(1 << ch2) | /* start both channels */
+               LRADC_DELAY_TRIGGER_DELAYS(0) |
+               LRADC_DELAY_LOOP(lradc->over_sample_cnt - 1) |
+               LRADC_DELAY_DELAY(lradc->over_sample_delay - 1),
+                                       LRADC_DELAY(3));
+
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(2) |
+                       LRADC_CTRL1_LRADC_IRQ(3) | LRADC_CTRL1_LRADC_IRQ(4) |
+                       LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
+
+       /* wake us again, when the conversions are done */
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(ch2), LRADC_CTRL1);
+       /*
+        * after changing the touchscreen plates setting
+        * the signals need some initial time to settle. Start the
+        * SoC's delay unit and start the conversion later
+        * and automatically.
+        */
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(0) | /* don't trigger ADC */
+               LRADC_DELAY_TRIGGER_DELAYS(1 << 3) | /* trigger DELAY unit#3 */
+               LRADC_DELAY_KICK |
+               LRADC_DELAY_DELAY(lradc->settling_delay), LRADC_DELAY(2));
+}
+
+static unsigned mxs_lradc_read_raw_channel(struct mxs_lradc *lradc,
+                                                       unsigned channel)
+{
+       u32 reg;
+       unsigned num_samples, val;
+
+       reg = readl(lradc->base + LRADC_CH(channel));
+       if (reg & LRADC_CH_ACCUMULATE)
+               num_samples = lradc->over_sample_cnt;
+       else
+               num_samples = 1;
+
+       val = (reg & LRADC_CH_VALUE_MASK) >> LRADC_CH_VALUE_OFFSET;
+       return val / num_samples;
+}
+
+static unsigned mxs_lradc_read_ts_pressure(struct mxs_lradc *lradc,
+                                               unsigned ch1, unsigned ch2)
+{
+       u32 reg, mask;
+       unsigned pressure, m1, m2;
+
+       mask = LRADC_CTRL1_LRADC_IRQ(ch1) | LRADC_CTRL1_LRADC_IRQ(ch2);
+       reg = readl(lradc->base + LRADC_CTRL1) & mask;
+
+       while (reg != mask) {
+               reg = readl(lradc->base + LRADC_CTRL1) & mask;
+               dev_dbg(lradc->dev, "One channel is still busy: %X\n", reg);
+       }
+
+       m1 = mxs_lradc_read_raw_channel(lradc, ch1);
+       m2 = mxs_lradc_read_raw_channel(lradc, ch2);
+
+       if (m2 == 0) {
+               dev_warn(lradc->dev, "Cannot calculate pressure\n");
+               return 1 << (LRADC_RESOLUTION - 1);
+       }
+
+       /* simply scale the value from 0 ... max ADC resolution */
+       pressure = m1;
+       pressure *= (1 << LRADC_RESOLUTION);
+       pressure /= m2;
+
+       dev_dbg(lradc->dev, "Pressure = %u\n", pressure);
+       return pressure;
+}
+
+#define TS_CH_XP 2
+#define TS_CH_YP 3
+#define TS_CH_XM 4
+#define TS_CH_YM 5
+
+static int mxs_lradc_read_ts_channel(struct mxs_lradc *lradc)
+{
+       u32 reg;
+       int val;
+
+       reg = readl(lradc->base + LRADC_CTRL1);
+
+       /* only channels 3 to 5 are of interest here */
+       if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YP)) {
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YP) |
+                       LRADC_CTRL1_LRADC_IRQ(TS_CH_YP), LRADC_CTRL1);
+               val = mxs_lradc_read_raw_channel(lradc, TS_CH_YP);
+       } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_XM)) {
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_XM) |
+                       LRADC_CTRL1_LRADC_IRQ(TS_CH_XM), LRADC_CTRL1);
+               val = mxs_lradc_read_raw_channel(lradc, TS_CH_XM);
+       } else if (reg & LRADC_CTRL1_LRADC_IRQ(TS_CH_YM)) {
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(TS_CH_YM) |
+                       LRADC_CTRL1_LRADC_IRQ(TS_CH_YM), LRADC_CTRL1);
+               val = mxs_lradc_read_raw_channel(lradc, TS_CH_YM);
+       } else {
+               return -EIO;
+       }
+
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
+
+       return val;
+}
+
+/*
+ * YP(open)--+-------------+
+ *           |             |--+
+ *           |             |  |
+ *    YM(-)--+-------------+  |
+ *             +--------------+
+ *             |              |
+ *         XP(weak+)        XM(open)
+ *
+ * "weak+" means 200k Ohm VDDIO
+ * (-) means GND
+ */
+static void mxs_lradc_setup_touch_detection(struct mxs_lradc *lradc)
+{
+       /*
+        * In order to detect a touch event the 'touch detect enable' bit
+        * enables:
+        *  - a weak pullup to the X+ connector
+        *  - a strong ground at the Y- connector
+        */
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+       mxs_lradc_reg_set(lradc, mxs_lradc_touch_detect_bit(lradc),
+                               LRADC_CTRL0);
+}
+
+/*
+ * YP(meas)--+-------------+
+ *           |             |--+
+ *           |             |  |
+ * YM(open)--+-------------+  |
+ *             +--------------+
+ *             |              |
+ *           XP(+)          XM(-)
+ *
+ * (+) means here 1.85 V
+ * (-) means here GND
+ */
+static void mxs_lradc_prepare_x_pos(struct mxs_lradc *lradc)
+{
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+       mxs_lradc_reg_set(lradc, mxs_lradc_drive_x_plate(lradc), LRADC_CTRL0);
+
+       lradc->cur_plate = LRADC_SAMPLE_X;
+       mxs_lradc_setup_ts_channel(lradc, TS_CH_YP);
+}
+
+/*
+ *   YP(+)--+-------------+
+ *          |             |--+
+ *          |             |  |
+ *   YM(-)--+-------------+  |
+ *            +--------------+
+ *            |              |
+ *         XP(open)        XM(meas)
+ *
+ * (+) means here 1.85 V
+ * (-) means here GND
+ */
+static void mxs_lradc_prepare_y_pos(struct mxs_lradc *lradc)
+{
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+       mxs_lradc_reg_set(lradc, mxs_lradc_drive_y_plate(lradc), LRADC_CTRL0);
+
+       lradc->cur_plate = LRADC_SAMPLE_Y;
+       mxs_lradc_setup_ts_channel(lradc, TS_CH_XM);
+}
+
+/*
+ *    YP(+)--+-------------+
+ *           |             |--+
+ *           |             |  |
+ * YM(meas)--+-------------+  |
+ *             +--------------+
+ *             |              |
+ *          XP(meas)        XM(-)
+ *
+ * (+) means here 1.85 V
+ * (-) means here GND
+ */
+static void mxs_lradc_prepare_pressure(struct mxs_lradc *lradc)
+{
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+       mxs_lradc_reg_set(lradc, mxs_lradc_drive_pressure(lradc), LRADC_CTRL0);
+
+       lradc->cur_plate = LRADC_SAMPLE_PRESSURE;
+       mxs_lradc_setup_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
+}
+
+static void mxs_lradc_enable_touch_detection(struct mxs_lradc *lradc)
+{
+       mxs_lradc_setup_touch_detection(lradc);
+
+       lradc->cur_plate = LRADC_TOUCH;
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ |
+                               LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+}
+
+static void mxs_lradc_report_ts_event(struct mxs_lradc *lradc)
+{
+       input_report_abs(lradc->ts_input, ABS_X, lradc->ts_x_pos);
+       input_report_abs(lradc->ts_input, ABS_Y, lradc->ts_y_pos);
+       input_report_abs(lradc->ts_input, ABS_PRESSURE, lradc->ts_pressure);
+       input_report_key(lradc->ts_input, BTN_TOUCH, 1);
+       input_sync(lradc->ts_input);
+}
+
+static void mxs_lradc_complete_touch_event(struct mxs_lradc *lradc)
+{
+       mxs_lradc_setup_touch_detection(lradc);
+       lradc->cur_plate = LRADC_SAMPLE_VALID;
+       /*
+        * start a dummy conversion to burn time to settle the signals
+        * note: we are not interested in the conversion's value
+        */
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(5));
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ(5), LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(5), LRADC_CTRL1);
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_TRIGGER(1 << 5) |
+               LRADC_DELAY_KICK | LRADC_DELAY_DELAY(10), /* waste 5 ms */
+                       LRADC_DELAY(2));
+}
+
+/*
+ * in order to avoid false measurements, report only samples where
+ * the surface is still touched after the position measurement
+ */
+static void mxs_lradc_finish_touch_event(struct mxs_lradc *lradc, bool valid)
+{
+       /* if it is still touched, report the sample */
+       if (valid && mxs_lradc_check_touch_event(lradc)) {
+               lradc->ts_valid = true;
+               mxs_lradc_report_ts_event(lradc);
+       }
+
+       /* if it is even still touched, continue with the next measurement */
+       if (mxs_lradc_check_touch_event(lradc)) {
+               mxs_lradc_prepare_y_pos(lradc);
+               return;
+       }
+
+       if (lradc->ts_valid) {
+               /* signal the release */
+               lradc->ts_valid = false;
+               input_report_key(lradc->ts_input, BTN_TOUCH, 0);
+               input_sync(lradc->ts_input);
+       }
+
+       /* if it is released, wait for the next touch via IRQ */
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ, LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN, LRADC_CTRL1);
+}
+
+/* touchscreen's state machine */
+static void mxs_lradc_handle_touch(struct mxs_lradc *lradc)
+{
+       int val;
+
+       switch (lradc->cur_plate) {
+       case LRADC_TOUCH:
+               /*
+                * start with the Y-pos, because it uses nearly the same plate
+                * settings like the touch detection
+                */
+               if (mxs_lradc_check_touch_event(lradc)) {
+                       mxs_lradc_reg_clear(lradc,
+                                       LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
+                                       LRADC_CTRL1);
+                       mxs_lradc_prepare_y_pos(lradc);
+               }
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ,
+                                       LRADC_CTRL1);
+               return;
+
+       case LRADC_SAMPLE_Y:
+               val = mxs_lradc_read_ts_channel(lradc);
+               if (val < 0) {
+                       mxs_lradc_enable_touch_detection(lradc); /* re-start */
+                       return;
+               }
+               lradc->ts_y_pos = val;
+               mxs_lradc_prepare_x_pos(lradc);
+               return;
+
+       case LRADC_SAMPLE_X:
+               val = mxs_lradc_read_ts_channel(lradc);
+               if (val < 0) {
+                       mxs_lradc_enable_touch_detection(lradc); /* re-start */
+                       return;
+               }
+               lradc->ts_x_pos = val;
+               mxs_lradc_prepare_pressure(lradc);
+               return;
+
+       case LRADC_SAMPLE_PRESSURE:
+               lradc->ts_pressure =
+                       mxs_lradc_read_ts_pressure(lradc, TS_CH_XP, TS_CH_YM);
+               mxs_lradc_complete_touch_event(lradc);
+               return;
+
+       case LRADC_SAMPLE_VALID:
+               val = mxs_lradc_read_ts_channel(lradc); /* ignore the value */
+               mxs_lradc_finish_touch_event(lradc, 1);
+               break;
+       }
+}
+
 /*
  * Raw I/O operations
  */
@@ -262,21 +790,20 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
         * Virtual channel 0 is always used here as the others are always not
         * used if doing raw sampling.
         */
-       writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
-       writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+       if (lradc->soc == IMX28_LRADC)
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
+                       LRADC_CTRL1);
+       mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
 
        /* Clean the slot's previous content, then set new one. */
-       writel(LRADC_CTRL4_LRADCSELECT_MASK(0),
-               lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
-       writel(chan->channel, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0), LRADC_CTRL4);
+       mxs_lradc_reg_set(lradc, chan->channel, LRADC_CTRL4);
 
-       writel(0, lradc->base + LRADC_CH(0));
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(0));
 
        /* Enable the IRQ and start sampling the channel. */
-       writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
-       writel(1 << 0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+       mxs_lradc_reg_set(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, 1 << 0, LRADC_CTRL0);
 
        /* Wait for completion on the channel, 1 second max. */
        ret = wait_for_completion_killable_timeout(&lradc->completion, HZ);
@@ -290,8 +817,7 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
        ret = IIO_VAL_INT;
 
 err:
-       writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_LRADC_IRQ_EN(0), LRADC_CTRL1);
 
        mutex_unlock(&lradc->lock);
 
@@ -303,220 +829,33 @@ static const struct iio_info mxs_lradc_iio_info = {
        .read_raw               = mxs_lradc_read_raw,
 };
 
-/*
- * Touchscreen handling
- */
-enum lradc_ts_plate {
-       LRADC_SAMPLE_X,
-       LRADC_SAMPLE_Y,
-       LRADC_SAMPLE_PRESSURE,
-};
-
-static int mxs_lradc_ts_touched(struct mxs_lradc *lradc)
-{
-       uint32_t reg;
-
-       /* Enable touch detection. */
-       writel(LRADC_CTRL0_PLATE_MASK,
-               lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
-       writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
-               lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
-
-       msleep(LRADC_TS_SAMPLE_DELAY_MS);
-
-       reg = readl(lradc->base + LRADC_STATUS);
-
-       return reg & LRADC_STATUS_TOUCH_DETECT_RAW;
-}
-
-static int32_t mxs_lradc_ts_sample(struct mxs_lradc *lradc,
-                               enum lradc_ts_plate plate, int change)
-{
-       unsigned long delay, jiff;
-       uint32_t reg, ctrl0 = 0, chan = 0;
-       /* The touchscreen always uses CTRL4 slot #7. */
-       const uint8_t slot = 7;
-       uint32_t val;
-
-       /*
-        * There are three correct configurations of the controller sampling
-        * the touchscreen, each of these configuration provides different
-        * information from the touchscreen.
-        *
-        * The following table describes the sampling configurations:
-        * +-------------+-------+-------+-------+
-        * | Wire \ Axis |   X   |   Y   |   Z   |
-        * +---------------------+-------+-------+
-        * |   X+ (CH2)  |   HI  |   TS  |   TS  |
-        * +-------------+-------+-------+-------+
-        * |   X- (CH4)  |   LO  |   SH  |   HI  |
-        * +-------------+-------+-------+-------+
-        * |   Y+ (CH3)  |   SH  |   HI  |   HI  |
-        * +-------------+-------+-------+-------+
-        * |   Y- (CH5)  |   TS  |   LO  |   SH  |
-        * +-------------+-------+-------+-------+
-        *
-        * HI ... strong '1'  ; LO ... strong '0'
-        * SH ... sample here ; TS ... tri-state
-        *
-        * There are a few other ways of obtaining the Z coordinate
-        * (aka. pressure), but the one in the table seems to be the
-        * most reliable one.
-        */
-       switch (plate) {
-       case LRADC_SAMPLE_X:
-               ctrl0 = LRADC_CTRL0_XPPSW | LRADC_CTRL0_XNNSW;
-               chan = 3;
-               break;
-       case LRADC_SAMPLE_Y:
-               ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_YNNSW;
-               chan = 4;
-               break;
-       case LRADC_SAMPLE_PRESSURE:
-               ctrl0 = LRADC_CTRL0_YPPSW | LRADC_CTRL0_XNNSW;
-               chan = 5;
-               break;
-       }
-
-       if (change) {
-               writel(LRADC_CTRL0_PLATE_MASK,
-                       lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
-               writel(ctrl0, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
-
-               writel(LRADC_CTRL4_LRADCSELECT_MASK(slot),
-                       lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
-               writel(chan << LRADC_CTRL4_LRADCSELECT_OFFSET(slot),
-                       lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
-       }
-
-       writel(0xffffffff, lradc->base + LRADC_CH(slot) + STMP_OFFSET_REG_CLR);
-       writel(1 << slot, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
-
-       delay = jiffies + msecs_to_jiffies(LRADC_TS_SAMPLE_DELAY_MS);
-       do {
-               jiff = jiffies;
-               reg = readl_relaxed(lradc->base + LRADC_CTRL1);
-               if (reg & LRADC_CTRL1_LRADC_IRQ(slot))
-                       break;
-       } while (time_before(jiff, delay));
-
-       writel(LRADC_CTRL1_LRADC_IRQ(slot),
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
-
-       if (time_after_eq(jiff, delay))
-               return -ETIMEDOUT;
-
-       val = readl(lradc->base + LRADC_CH(slot));
-       val &= LRADC_CH_VALUE_MASK;
-
-       return val;
-}
-
-static int32_t mxs_lradc_ts_sample_filter(struct mxs_lradc *lradc,
-                               enum lradc_ts_plate plate)
-{
-       int32_t val, tot = 0;
-       int i;
-
-       val = mxs_lradc_ts_sample(lradc, plate, 1);
-
-       /* Delay a bit so the touchscreen is stable. */
-       mdelay(2);
-
-       for (i = 0; i < LRADC_TS_SAMPLE_AMOUNT; i++) {
-               val = mxs_lradc_ts_sample(lradc, plate, 0);
-               tot += val;
-       }
-
-       return tot / LRADC_TS_SAMPLE_AMOUNT;
-}
-
-static void mxs_lradc_ts_work(struct work_struct *ts_work)
-{
-       struct mxs_lradc *lradc = container_of(ts_work,
-                               struct mxs_lradc, ts_work);
-       int val_x, val_y, val_p;
-       bool valid = false;
-
-       while (mxs_lradc_ts_touched(lradc)) {
-               /* Disable touch detector so we can sample the touchscreen. */
-               writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
-                       lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
-
-               if (likely(valid)) {
-                       input_report_abs(lradc->ts_input, ABS_X, val_x);
-                       input_report_abs(lradc->ts_input, ABS_Y, val_y);
-                       input_report_abs(lradc->ts_input, ABS_PRESSURE, val_p);
-                       input_report_key(lradc->ts_input, BTN_TOUCH, 1);
-                       input_sync(lradc->ts_input);
-               }
-
-               valid = false;
-
-               val_x = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_X);
-               if (val_x < 0)
-                       continue;
-               val_y = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_Y);
-               if (val_y < 0)
-                       continue;
-               val_p = mxs_lradc_ts_sample_filter(lradc, LRADC_SAMPLE_PRESSURE);
-               if (val_p < 0)
-                       continue;
-
-               valid = true;
-       }
-
-       input_report_abs(lradc->ts_input, ABS_PRESSURE, 0);
-       input_report_key(lradc->ts_input, BTN_TOUCH, 0);
-       input_sync(lradc->ts_input);
-
-       /* Do not restart the TS IRQ if the driver is shutting down. */
-       if (lradc->stop_touchscreen)
-               return;
-
-       /* Restart the touchscreen interrupts. */
-       writel(LRADC_CTRL1_TOUCH_DETECT_IRQ,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
-       writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
-}
-
 static int mxs_lradc_ts_open(struct input_dev *dev)
 {
        struct mxs_lradc *lradc = input_get_drvdata(dev);
 
-       /* The touchscreen is starting. */
-       lradc->stop_touchscreen = false;
-
        /* Enable the touch-detect circuitry. */
-       writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
-               lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
-
-       /* Enable the touch-detect IRQ. */
-       writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
+       mxs_lradc_enable_touch_detection(lradc);
 
        return 0;
 }
 
-static void mxs_lradc_ts_close(struct input_dev *dev)
+static void mxs_lradc_disable_ts(struct mxs_lradc *lradc)
 {
-       struct mxs_lradc *lradc = input_get_drvdata(dev);
-
-       /* Indicate the touchscreen is stopping. */
-       lradc->stop_touchscreen = true;
-       mb();
+       /* stop all interrupts from firing */
+       mxs_lradc_reg_clear(lradc, LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
+               LRADC_CTRL1_LRADC_IRQ_EN(2) | LRADC_CTRL1_LRADC_IRQ_EN(3) |
+               LRADC_CTRL1_LRADC_IRQ_EN(4) | LRADC_CTRL1_LRADC_IRQ_EN(5),
+               LRADC_CTRL1);
 
-       /* Wait until touchscreen thread finishes any possible remnants. */
-       cancel_work_sync(&lradc->ts_work);
+       /* Power-down touchscreen touch-detect circuitry. */
+       mxs_lradc_reg_clear(lradc, mxs_lradc_plate_mask(lradc), LRADC_CTRL0);
+}
 
-       /* Disable touchscreen touch-detect IRQ. */
-       writel(LRADC_CTRL1_TOUCH_DETECT_IRQ_EN,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+static void mxs_lradc_ts_close(struct input_dev *dev)
+{
+       struct mxs_lradc *lradc = input_get_drvdata(dev);
 
-       /* Power-down touchscreen touch-detect circuitry. */
-       writel(LRADC_CTRL0_TOUCH_DETECT_ENABLE,
-               lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+       mxs_lradc_disable_ts(lradc);
 }
 
 static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
@@ -562,8 +901,7 @@ static void mxs_lradc_ts_unregister(struct mxs_lradc *lradc)
        if (!lradc->use_touchscreen)
                return;
 
-       cancel_work_sync(&lradc->ts_work);
-
+       mxs_lradc_disable_ts(lradc);
        input_unregister_device(lradc->ts_input);
 }
 
@@ -576,31 +914,24 @@ static irqreturn_t mxs_lradc_handle_irq(int irq, void *data)
        struct mxs_lradc *lradc = iio_priv(iio);
        unsigned long reg = readl(lradc->base + LRADC_CTRL1);
        const uint32_t ts_irq_mask =
-               LRADC_CTRL1_TOUCH_DETECT_IRQ_EN |
-               LRADC_CTRL1_TOUCH_DETECT_IRQ;
+               LRADC_CTRL1_TOUCH_DETECT_IRQ |
+               LRADC_CTRL1_LRADC_IRQ(2) |
+               LRADC_CTRL1_LRADC_IRQ(3) |
+               LRADC_CTRL1_LRADC_IRQ(4) |
+               LRADC_CTRL1_LRADC_IRQ(5);
 
-       if (!(reg & LRADC_CTRL1_LRADC_IRQ_MASK))
+       if (!(reg & mxs_lradc_irq_mask(lradc)))
                return IRQ_NONE;
 
-       /*
-        * Touchscreen IRQ handling code has priority and therefore
-        * is placed here. In case touchscreen IRQ arrives, disable
-        * it ASAP
-        */
-       if (reg & LRADC_CTRL1_TOUCH_DETECT_IRQ) {
-               writel(ts_irq_mask,
-                       lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
-               if (!lradc->stop_touchscreen)
-                       schedule_work(&lradc->ts_work);
-       }
+       if (lradc->use_touchscreen && (reg & ts_irq_mask))
+               mxs_lradc_handle_touch(lradc);
 
        if (iio_buffer_enabled(iio))
                iio_trigger_poll(iio->trig, iio_get_time_ns());
        else if (reg & LRADC_CTRL1_LRADC_IRQ(0))
                complete(&lradc->completion);
 
-       writel(reg & LRADC_CTRL1_LRADC_IRQ_MASK,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+       mxs_lradc_reg_clear(lradc, reg & mxs_lradc_irq_mask(lradc), LRADC_CTRL1);
 
        return IRQ_HANDLED;
 }
@@ -619,19 +950,13 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
 
        for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
                lradc->buffer[j] = readl(lradc->base + LRADC_CH(j));
-               writel(chan_value, lradc->base + LRADC_CH(j));
+               mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(j));
                lradc->buffer[j] &= LRADC_CH_VALUE_MASK;
                lradc->buffer[j] /= LRADC_DELAY_TIMER_LOOP;
                j++;
        }
 
-       if (iio->scan_timestamp) {
-               s64 *timestamp = (s64 *)((u8 *)lradc->buffer +
-                                       ALIGN(j, sizeof(s64)));
-               *timestamp = pf->timestamp;
-       }
-
-       iio_push_to_buffers(iio, (u8 *)lradc->buffer);
+       iio_push_to_buffers_with_timestamp(iio, lradc->buffer, pf->timestamp);
 
        iio_trigger_notify_done(iio->trig);
 
@@ -644,7 +969,7 @@ static int mxs_lradc_configure_trigger(struct iio_trigger *trig, bool state)
        struct mxs_lradc *lradc = iio_priv(iio);
        const uint32_t st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR;
 
-       writel(LRADC_DELAY_KICK, lradc->base + LRADC_DELAY(0) + st);
+       mxs_lradc_reg_wrt(lradc, LRADC_DELAY_KICK, LRADC_DELAY(0) + st);
 
        return 0;
 }
@@ -716,38 +1041,30 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
                goto err_mem;
        }
 
-       ret = iio_sw_buffer_preenable(iio);
-       if (ret < 0)
-               goto err_buf;
-
-       writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
-       writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+       if (lradc->soc == IMX28_LRADC)
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
+                                                       LRADC_CTRL1);
+       mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
 
        for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
                ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
                ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs);
                ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
-               writel(chan_value, lradc->base + LRADC_CH(ofs));
+               mxs_lradc_reg_wrt(lradc, chan_value, LRADC_CH(ofs));
                bitmap_set(&enable, ofs, 1);
                ofs++;
        }
 
-       writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
-               lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
-
-       writel(ctrl4_clr, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
-       writel(ctrl4_set, lradc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
-
-       writel(ctrl1_irq, lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
-
-       writel(enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
-               lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_SET);
+       mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
+                                       LRADC_DELAY_KICK, LRADC_DELAY(0));
+       mxs_lradc_reg_clear(lradc, ctrl4_clr, LRADC_CTRL4);
+       mxs_lradc_reg_set(lradc, ctrl4_set, LRADC_CTRL4);
+       mxs_lradc_reg_set(lradc, ctrl1_irq, LRADC_CTRL1);
+       mxs_lradc_reg_set(lradc, enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
+                                       LRADC_DELAY(0));
 
        return 0;
 
-err_buf:
-       kfree(lradc->buffer);
 err_mem:
        mutex_unlock(&lradc->lock);
        return ret;
@@ -757,12 +1074,13 @@ static int mxs_lradc_buffer_postdisable(struct iio_dev *iio)
 {
        struct mxs_lradc *lradc = iio_priv(iio);
 
-       writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
-               lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
+       mxs_lradc_reg_clear(lradc, LRADC_DELAY_TRIGGER_LRADCS_MASK |
+                                       LRADC_DELAY_KICK, LRADC_DELAY(0));
 
-       writel(0xff, lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
-       writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+       mxs_lradc_reg_clear(lradc, 0xff, LRADC_CTRL0);
+       if (lradc->soc == IMX28_LRADC)
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL1_MX28_LRADC_IRQ_EN_MASK,
+                                       LRADC_CTRL1);
 
        kfree(lradc->buffer);
        mutex_unlock(&lradc->lock);
@@ -857,24 +1175,25 @@ static int mxs_lradc_hw_init(struct mxs_lradc *lradc)
                return ret;
 
        /* Configure DELAY CHANNEL 0 for generic ADC sampling. */
-       writel(adc_cfg, lradc->base + LRADC_DELAY(0));
+       mxs_lradc_reg_wrt(lradc, adc_cfg, LRADC_DELAY(0));
 
        /* Disable remaining DELAY CHANNELs */
-       writel(0, lradc->base + LRADC_DELAY(1));
-       writel(0, lradc->base + LRADC_DELAY(2));
-       writel(0, lradc->base + LRADC_DELAY(3));
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(1));
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(2));
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(3));
 
        /* Configure the touchscreen type */
-       writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE,
-               lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
+       if (lradc->soc == IMX28_LRADC) {
+               mxs_lradc_reg_clear(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
+                                                       LRADC_CTRL0);
 
-       if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE) {
-               writel(LRADC_CTRL0_TOUCH_SCREEN_TYPE,
-                       lradc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);
+       if (lradc->use_touchscreen == MXS_LRADC_TOUCHSCREEN_5WIRE)
+               mxs_lradc_reg_set(lradc, LRADC_CTRL0_MX28_TOUCH_SCREEN_TYPE,
+                               LRADC_CTRL0);
        }
 
        /* Start internal temperature sensing. */
-       writel(0, lradc->base + LRADC_CTRL2);
+       mxs_lradc_reg_wrt(lradc, 0, LRADC_CTRL2);
 
        return 0;
 }
@@ -883,11 +1202,10 @@ static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
 {
        int i;
 
-       writel(LRADC_CTRL1_LRADC_IRQ_EN_MASK,
-               lradc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
+       mxs_lradc_reg_clear(lradc, mxs_lradc_irq_en_mask(lradc), LRADC_CTRL1);
 
        for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++)
-               writel(0, lradc->base + LRADC_DELAY(i));
+               mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(i));
 }
 
 static const struct of_device_id mxs_lradc_dt_ids[] = {
@@ -897,6 +1215,52 @@ static const struct of_device_id mxs_lradc_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, mxs_lradc_dt_ids);
 
+static int mxs_lradc_probe_touchscreen(struct mxs_lradc *lradc,
+                                               struct device_node *lradc_node)
+{
+       int ret;
+       u32 ts_wires = 0, adapt;
+
+       ret = of_property_read_u32(lradc_node, "fsl,lradc-touchscreen-wires",
+                               &ts_wires);
+       if (ret)
+               return -ENODEV; /* touchscreen feature disabled */
+
+       switch (ts_wires) {
+       case 4:
+               lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
+               break;
+       case 5:
+               if (lradc->soc == IMX28_LRADC) {
+                       lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
+                       break;
+               }
+               /* fall through an error message for i.MX23 */
+       default:
+               dev_err(lradc->dev,
+                       "Unsupported number of touchscreen wires (%d)\n",
+                       ts_wires);
+               return -EINVAL;
+       }
+
+       lradc->over_sample_cnt = 4;
+       ret = of_property_read_u32(lradc_node, "fsl,ave-ctrl", &adapt);
+       if (ret == 0)
+               lradc->over_sample_cnt = adapt;
+
+       lradc->over_sample_delay = 2;
+       ret = of_property_read_u32(lradc_node, "fsl,ave-delay", &adapt);
+       if (ret == 0)
+               lradc->over_sample_delay = adapt;
+
+       lradc->settling_delay = 10;
+       ret = of_property_read_u32(lradc_node, "fsl,settling", &adapt);
+       if (ret == 0)
+               lradc->settling_delay = adapt;
+
+       return 0;
+}
+
 static int mxs_lradc_probe(struct platform_device *pdev)
 {
        const struct of_device_id *of_id =
@@ -908,8 +1272,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
        struct mxs_lradc *lradc;
        struct iio_dev *iio;
        struct resource *iores;
-       uint32_t ts_wires = 0;
-       int ret = 0;
+       int ret = 0, touch_ret;
        int i;
 
        /* Allocate the IIO device. */
@@ -920,6 +1283,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
        }
 
        lradc = iio_priv(iio);
+       lradc->soc = (enum mxs_lradc_id)of_id->data;
 
        /* Grab the memory area */
        iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -928,20 +1292,18 @@ static int mxs_lradc_probe(struct platform_device *pdev)
        if (IS_ERR(lradc->base))
                return PTR_ERR(lradc->base);
 
-       INIT_WORK(&lradc->ts_work, mxs_lradc_ts_work);
+       lradc->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(lradc->clk)) {
+               dev_err(dev, "Failed to get the delay unit clock\n");
+               return PTR_ERR(lradc->clk);
+       }
+       ret = clk_prepare_enable(lradc->clk);
+       if (ret != 0) {
+               dev_err(dev, "Failed to enable the delay unit clock\n");
+               return ret;
+       }
 
-       /* Check if touchscreen is enabled in DT. */
-       ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
-                               &ts_wires);
-       if (ret)
-               dev_info(dev, "Touchscreen not enabled.\n");
-       else if (ts_wires == 4)
-               lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_4WIRE;
-       else if (ts_wires == 5)
-               lradc->use_touchscreen = MXS_LRADC_TOUCHSCREEN_5WIRE;
-       else
-               dev_warn(dev, "Unsupported number of touchscreen wires (%d)\n",
-                               ts_wires);
+       touch_ret = mxs_lradc_probe_touchscreen(lradc, node);
 
        /* Grab all IRQ sources */
        for (i = 0; i < of_cfg->irq_count; i++) {
@@ -985,9 +1347,11 @@ static int mxs_lradc_probe(struct platform_device *pdev)
                goto err_dev;
 
        /* Register the touchscreen input device. */
-       ret = mxs_lradc_ts_register(lradc);
-       if (ret)
-               goto err_dev;
+       if (touch_ret == 0) {
+               ret = mxs_lradc_ts_register(lradc);
+               if (ret)
+                       goto err_ts_register;
+       }
 
        /* Register IIO device. */
        ret = iio_device_register(iio);
@@ -1000,6 +1364,8 @@ static int mxs_lradc_probe(struct platform_device *pdev)
 
 err_ts:
        mxs_lradc_ts_unregister(lradc);
+err_ts_register:
+       mxs_lradc_hw_stop(lradc);
 err_dev:
        mxs_lradc_trigger_remove(iio);
 err_trig:
@@ -1012,14 +1378,13 @@ static int mxs_lradc_remove(struct platform_device *pdev)
        struct iio_dev *iio = platform_get_drvdata(pdev);
        struct mxs_lradc *lradc = iio_priv(iio);
 
+       iio_device_unregister(iio);
        mxs_lradc_ts_unregister(lradc);
-
        mxs_lradc_hw_stop(lradc);
-
-       iio_device_unregister(iio);
-       iio_triggered_buffer_cleanup(iio);
        mxs_lradc_trigger_remove(iio);
+       iio_triggered_buffer_cleanup(iio);
 
+       clk_disable_unprepare(lradc->clk);
        return 0;
 }
 
@@ -1038,3 +1403,4 @@ module_platform_driver(mxs_lradc_driver);
 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
 MODULE_DESCRIPTION("Freescale i.MX28 LRADC driver");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
index 20f2d555e7cdc695ede30907abaf40e6561b170f..970d9edc73b6cc0d978a6a21a100de6c1a7a6994 100644 (file)
@@ -146,7 +146,6 @@ static int spear_read_raw(struct iio_dev *indio_dev,
                          long mask)
 {
        struct spear_adc_info *info = iio_priv(indio_dev);
-       u32 scale_mv;
        u32 status;
 
        switch (mask) {
@@ -168,10 +167,9 @@ static int spear_read_raw(struct iio_dev *indio_dev,
                return IIO_VAL_INT;
 
        case IIO_CHAN_INFO_SCALE:
-               scale_mv = (info->vref_external * 1000) >> DATA_BITS;
-               *val =  scale_mv / 1000;
-               *val2 = (scale_mv % 1000) * 1000;
-               return IIO_VAL_INT_PLUS_MICRO;
+               *val = info->vref_external;
+               *val2 = DATA_BITS;
+               return IIO_VAL_FRACTIONAL_LOG2;
        }
 
        return -EINVAL;
@@ -320,7 +318,7 @@ static int spear_adc_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
        info->adc_base_spear3xx =
-               (struct adc_regs_spear3xx *)info->adc_base_spear6xx;
+               (struct adc_regs_spear3xx __iomem *)info->adc_base_spear6xx;
 
        info->clk = clk_get(dev, NULL);
        if (IS_ERR(info->clk)) {
@@ -335,7 +333,7 @@ static int spear_adc_probe(struct platform_device *pdev)
        }
 
        irq = platform_get_irq(pdev, 0);
-       if ((irq < 0) || (irq >= NR_IRQS)) {
+       if (irq <= 0) {
                dev_err(dev, "failed getting interrupt resource\n");
                ret = -EINVAL;
                goto errout3;
index ce7d91cb331c015e031213e95fb4ed4e6c40807e..0feea5541d02d5f98f24023ffcd4623480a0cc6b 100644 (file)
@@ -138,6 +138,5 @@ static struct i2c_driver adt7316_driver = {
 module_i2c_driver(adt7316_driver);
 
 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and"
-                       "ADT7516/7/8 digital temperature sensor, ADC and DAC");
+MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and ADT7516/7/8 digital temperature sensor, ADC and DAC");
 MODULE_LICENSE("GPL v2");
index 0db8ef5835a07761e5472b160ca3c263997f2ced..7f4f0a8245b480090387c0f03aab24dbbb8ee178 100644 (file)
@@ -146,6 +146,5 @@ static struct spi_driver adt7316_driver = {
 module_spi_driver(adt7316_driver);
 
 MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
-MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and"
-                       "ADT7516/7/9 digital temperature sensor, ADC and DAC");
+MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and ADT7516/7/9 digital temperature sensor, ADC and DAC");
 MODULE_LICENSE("GPL v2");
index 1e1356825d6dadd98b7e9d14e8bc3a896890080d..80266e801d5673919533c9208241b3a0e3868d7f 100644 (file)
@@ -412,13 +412,13 @@ static ssize_t adt7316_store_ad_channel(struct device *dev,
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
        u8 config2;
-       unsigned long data = 0;
+       u8 data;
        int ret;
 
        if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
                return -EPERM;
 
-       ret = strict_strtoul(buf, 10, &data);
+       ret = kstrtou8(buf, 10, &data);
        if (ret)
                return -EINVAL;
 
@@ -823,10 +823,10 @@ static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev,
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
        u8 dac_config;
-       unsigned long data = 0;
+       u8 data;
        int ret;
 
-       ret = strict_strtoul(buf, 16, &data);
+       ret = kstrtou8(buf, 16, &data);
        if (ret || data > ADT7316_DA_2VREF_CH_MASK)
                return -EINVAL;
 
@@ -878,13 +878,13 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev,
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
        u8 dac_config;
-       unsigned long data;
+       u8 data;
        int ret;
 
        if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
                return -EPERM;
 
-       ret = strict_strtoul(buf, 10, &data);
+       ret = kstrtou8(buf, 10, &data);
        if (ret || data > ADT7316_DA_EN_MODE_MASK)
                return -EINVAL;
 
@@ -933,7 +933,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
        u8 ldac_config;
-       unsigned long data;
+       u8 data;
        int ret;
 
        if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) {
@@ -941,7 +941,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
                        ADT7316_DA_EN_MODE_LDAC)
                        return -EPERM;
 
-               ret = strict_strtoul(buf, 16, &data);
+               ret = kstrtou8(buf, 16, &data);
                if (ret || data > ADT7316_LDAC_EN_DA_MASK)
                        return -EINVAL;
 
@@ -1079,11 +1079,11 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
        u8 ldac_config;
-       unsigned long data;
+       u8 data;
        int ret;
 
        if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
-               ret = strict_strtoul(buf, 16, &data);
+               ret = kstrtou8(buf, 16, &data);
                if (ret || data > 3)
                        return -EINVAL;
 
@@ -1093,7 +1093,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
                else if (data & 0x2)
                        ldac_config |= ADT7516_DAC_CD_IN_VREF;
        } else {
-               ret = strict_strtoul(buf, 16, &data);
+               ret = kstrtou8(buf, 16, &data);
                if (ret)
                        return -EINVAL;
 
@@ -1281,11 +1281,11 @@ static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
 static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip,
                int offset_addr, const char *buf, size_t len)
 {
-       long data;
+       int data;
        u8 val;
        int ret;
 
-       ret = strict_strtol(buf, 10, &data);
+       ret = kstrtoint(buf, 10, &data);
        if (ret || data > 127 || data < -128)
                return -EINVAL;
 
@@ -1442,7 +1442,7 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
                int channel, const char *buf, size_t len)
 {
        u8 msb, lsb, offset;
-       unsigned long data;
+       u16 data;
        int ret;
 
        if (channel >= ADT7316_DA_MSB_DATA_REGS ||
@@ -1454,7 +1454,7 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
 
        offset = chip->dac_bits - 8;
 
-       ret = strict_strtoul(buf, 10, &data);
+       ret = kstrtou16(buf, 10, &data);
        if (ret || data >= (1 << chip->dac_bits))
                return -EINVAL;
 
@@ -1830,11 +1830,11 @@ static ssize_t adt7316_set_int_mask(struct device *dev,
 {
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
-       unsigned long data;
+       u16 data;
        int ret;
        u8 mask;
 
-       ret = strict_strtoul(buf, 16, &data);
+       ret = kstrtou16(buf, 16, &data);
        if (ret || data >= ADT7316_VDD_INT_MASK + 1)
                return -EINVAL;
 
@@ -1901,7 +1901,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        struct iio_dev *dev_info = dev_to_iio_dev(dev);
        struct adt7316_chip_info *chip = iio_priv(dev_info);
-       long data;
+       int data;
        u8 val;
        int ret;
 
@@ -1909,7 +1909,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
                this_attr->address > ADT7316_EX_TEMP_LOW)
                return -EPERM;
 
-       ret = strict_strtol(buf, 10, &data);
+       ret = kstrtoint(buf, 10, &data);
        if (ret)
                return -EINVAL;
 
@@ -2106,11 +2106,9 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
        unsigned short *adt7316_platform_data = dev->platform_data;
        int ret = 0;
 
-       indio_dev = iio_device_alloc(sizeof(*chip));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(dev, sizeof(*chip));
+       if (!indio_dev)
+               return -ENOMEM;
        chip = iio_priv(indio_dev);
        /* this is only used for device removal purposes */
        dev_set_drvdata(dev, indio_dev);
@@ -2146,58 +2144,44 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
                if (adt7316_platform_data[0])
                        chip->bus.irq_flags = adt7316_platform_data[0];
 
-               ret = request_threaded_irq(chip->bus.irq,
-                                          NULL,
-                                          &adt7316_event_handler,
-                                          chip->bus.irq_flags | IRQF_ONESHOT,
-                                          indio_dev->name,
-                                          indio_dev);
+               ret = devm_request_threaded_irq(dev, chip->bus.irq,
+                                               NULL,
+                                               &adt7316_event_handler,
+                                               chip->bus.irq_flags |
+                                               IRQF_ONESHOT,
+                                               indio_dev->name,
+                                               indio_dev);
                if (ret)
-                       goto error_free_dev;
+                       return ret;
 
                if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
                        chip->config1 |= ADT7316_INT_POLARITY;
        }
 
        ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1);
-       if (ret) {
-               ret = -EIO;
-               goto error_unreg_irq;
-       }
+       if (ret)
+               return -EIO;
 
        ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3);
-       if (ret) {
-               ret = -EIO;
-               goto error_unreg_irq;
-       }
+       if (ret)
+               return -EIO;
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_unreg_irq;
+               return ret;
 
        dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
                        indio_dev->name);
 
        return 0;
-
-error_unreg_irq:
-       free_irq(chip->bus.irq, indio_dev);
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
-       return ret;
 }
 EXPORT_SYMBOL(adt7316_probe);
 
 int adt7316_remove(struct device *dev)
 {
        struct iio_dev *indio_dev = dev_get_drvdata(dev);
-       struct adt7316_chip_info *chip = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (chip->bus.irq)
-               free_irq(chip->bus.irq, indio_dev);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index f4a0341cc70c1355dcab30e6113c3cddba5a1a82..7e7f9890a642ad7816f05f4a1ffa3952ff6a0f8d 100644 (file)
@@ -123,14 +123,14 @@ static int ad7150_read_raw(struct iio_dev *indio_dev,
        }
 }
 
-static int ad7150_read_event_config(struct iio_dev *indio_dev, u64 event_code)
+static int ad7150_read_event_config(struct iio_dev *indio_dev,
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir)
 {
        int ret;
        u8 threshtype;
        bool adaptive;
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING);
 
        ret = i2c_smbus_read_byte_data(chip->client, AD7150_CFG);
        if (ret < 0)
@@ -139,42 +139,47 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, u64 event_code)
        threshtype = (ret >> 5) & 0x03;
        adaptive = !!(ret & 0x80);
 
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       switch (type) {
        case IIO_EV_TYPE_MAG_ADAPTIVE:
-               if (rising)
+               if (dir == IIO_EV_DIR_RISING)
                        return adaptive && (threshtype == 0x1);
                else
                        return adaptive && (threshtype == 0x0);
        case IIO_EV_TYPE_THRESH_ADAPTIVE:
-               if (rising)
+               if (dir == IIO_EV_DIR_RISING)
                        return adaptive && (threshtype == 0x3);
                else
                        return adaptive && (threshtype == 0x2);
 
        case IIO_EV_TYPE_THRESH:
-               if (rising)
+               if (dir == IIO_EV_DIR_RISING)
                        return !adaptive && (threshtype == 0x1);
                else
                        return !adaptive && (threshtype == 0x0);
+       default:
+               break;
        }
        return -EINVAL;
 }
 
 /* lock should be held */
-static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code)
+static int ad7150_write_event_params(struct iio_dev *indio_dev,
+        unsigned int chan, enum iio_event_type type,
+        enum iio_event_direction dir)
 {
        int ret;
        u16 value;
        u8 sens, timeout;
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
-       int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING);
+       int rising = (dir == IIO_EV_DIR_RISING);
+       u64 event_code;
+
+       event_code = IIO_UNMOD_EVENT_CODE(IIO_CAPACITANCE, chan, type, dir);
 
        if (event_code != chip->current_event)
                return 0;
 
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       switch (type) {
                /* Note completely different from the adaptive versions */
        case IIO_EV_TYPE_THRESH:
                value = chip->threshold[rising][chan];
@@ -211,18 +216,20 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code)
 }
 
 static int ad7150_write_event_config(struct iio_dev *indio_dev,
-                                    u64 event_code, int state)
+       const struct iio_chan_spec *chan, enum iio_event_type type,
+       enum iio_event_direction dir, int state)
 {
        u8 thresh_type, cfg, adaptive;
        int ret;
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING);
+       int rising = (dir == IIO_EV_DIR_RISING);
+       u64 event_code;
 
        /* Something must always be turned on */
        if (state == 0)
                return -EINVAL;
 
+       event_code = IIO_UNMOD_EVENT_CODE(chan->type, chan->channel, type, dir);
        if (event_code == chip->current_event)
                return 0;
        mutex_lock(&chip->state_lock);
@@ -232,7 +239,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
 
        cfg = ret & ~((0x03 << 5) | (0x1 << 7));
 
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       switch (type) {
        case IIO_EV_TYPE_MAG_ADAPTIVE:
                adaptive = 1;
                if (rising)
@@ -268,7 +275,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev,
        chip->current_event = event_code;
 
        /* update control attributes */
-       ret = ad7150_write_event_params(indio_dev, event_code);
+       ret = ad7150_write_event_params(indio_dev, chan->channel, type, dir);
 error_ret:
        mutex_unlock(&chip->state_lock);
 
@@ -276,53 +283,52 @@ error_ret:
 }
 
 static int ad7150_read_event_value(struct iio_dev *indio_dev,
-                                  u64 event_code,
-                                  int *val)
+                                  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)
 {
-       int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING);
+       int rising = (dir == IIO_EV_DIR_RISING);
 
        /* Complex register sharing going on here */
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       switch (type) {
        case IIO_EV_TYPE_MAG_ADAPTIVE:
-               *val = chip->mag_sensitivity[rising][chan];
-               return 0;
-
+               *val = chip->mag_sensitivity[rising][chan->channel];
+               return IIO_VAL_INT;
        case IIO_EV_TYPE_THRESH_ADAPTIVE:
-               *val = chip->thresh_sensitivity[rising][chan];
-               return 0;
-
+               *val = chip->thresh_sensitivity[rising][chan->channel];
+               return IIO_VAL_INT;
        case IIO_EV_TYPE_THRESH:
-               *val = chip->threshold[rising][chan];
-               return 0;
-
+               *val = chip->threshold[rising][chan->channel];
+               return IIO_VAL_INT;
        default:
                return -EINVAL;
-       };
+       }
 }
 
 static int ad7150_write_event_value(struct iio_dev *indio_dev,
-                                  u64 event_code,
-                                  int val)
+                                  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)
 {
        int ret;
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
-       int chan = IIO_EVENT_CODE_EXTRACT_CHAN(event_code);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                       IIO_EV_DIR_RISING);
+       int rising = (dir == IIO_EV_DIR_RISING);
 
        mutex_lock(&chip->state_lock);
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+       switch (type) {
        case IIO_EV_TYPE_MAG_ADAPTIVE:
-               chip->mag_sensitivity[rising][chan] = val;
+               chip->mag_sensitivity[rising][chan->channel] = val;
                break;
        case IIO_EV_TYPE_THRESH_ADAPTIVE:
-               chip->thresh_sensitivity[rising][chan] = val;
+               chip->thresh_sensitivity[rising][chan->channel] = val;
                break;
        case IIO_EV_TYPE_THRESH:
-               chip->threshold[rising][chan] = val;
+               chip->threshold[rising][chan->channel] = val;
                break;
        default:
                ret = -EINVAL;
@@ -330,7 +336,7 @@ static int ad7150_write_event_value(struct iio_dev *indio_dev,
        }
 
        /* write back if active */
-       ret = ad7150_write_event_params(indio_dev, event_code);
+       ret = ad7150_write_event_params(indio_dev, chan->channel, type, dir);
 
 error_ret:
        mutex_unlock(&chip->state_lock);
@@ -374,17 +380,22 @@ static ssize_t ad7150_store_timeout(struct device *dev,
        struct ad7150_chip_info *chip = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int chan = IIO_EVENT_CODE_EXTRACT_CHAN(this_attr->address);
-       int rising = !!(IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address) ==
-                       IIO_EV_DIR_RISING);
+       enum iio_event_direction dir;
+       enum iio_event_type type;
+       int rising;
        u8 data;
        int ret;
 
+       type = IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address);
+       dir = IIO_EVENT_CODE_EXTRACT_DIR(this_attr->address);
+       rising = (dir == IIO_EV_DIR_RISING);
+
        ret = kstrtou8(buf, 10, &data);
        if (ret < 0)
                return ret;
 
        mutex_lock(&chip->state_lock);
-       switch (IIO_EVENT_CODE_EXTRACT_TYPE(this_attr->address)) {
+       switch (type) {
        case IIO_EV_TYPE_MAG_ADAPTIVE:
                chip->mag_timeout[rising][chan] = data;
                break;
@@ -396,7 +407,7 @@ static ssize_t ad7150_store_timeout(struct device *dev,
                goto error_ret;
        }
 
-       ret = ad7150_write_event_params(indio_dev, this_attr->address);
+       ret = ad7150_write_event_params(indio_dev, chan, type, dir);
 error_ret:
        mutex_unlock(&chip->state_lock);
 
@@ -424,6 +435,40 @@ static AD7150_TIMEOUT(0, thresh_adaptive, falling, THRESH_ADAPTIVE, FALLING);
 static AD7150_TIMEOUT(1, thresh_adaptive, rising, THRESH_ADAPTIVE, RISING);
 static AD7150_TIMEOUT(1, thresh_adaptive, falling, THRESH_ADAPTIVE, FALLING);
 
+static const struct iio_event_spec ad7150_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_ADAPTIVE,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_THRESH_ADAPTIVE,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_MAG_ADAPTIVE,
+               .dir = IIO_EV_DIR_RISING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       }, {
+               .type = IIO_EV_TYPE_MAG_ADAPTIVE,
+               .dir = IIO_EV_DIR_FALLING,
+               .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+                       BIT(IIO_EV_INFO_ENABLE),
+       },
+};
+
 static const struct iio_chan_spec ad7150_channels[] = {
        {
                .type = IIO_CAPACITANCE,
@@ -431,26 +476,16 @@ static const struct iio_chan_spec ad7150_channels[] = {
                .channel = 0,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                BIT(IIO_CHAN_INFO_AVERAGE_RAW),
-               .event_mask =
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_FALLING) |
-               IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_FALLING)
+               .event_spec = ad7150_events,
+               .num_event_specs = ARRAY_SIZE(ad7150_events),
        }, {
                .type = IIO_CAPACITANCE,
                .indexed = 1,
                .channel = 1,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                BIT(IIO_CHAN_INFO_AVERAGE_RAW),
-               .event_mask =
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH_ADAPTIVE, IIO_EV_DIR_FALLING) |
-               IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_RISING) |
-               IIO_EV_BIT(IIO_EV_TYPE_MAG_ADAPTIVE, IIO_EV_DIR_FALLING)
+               .event_spec = ad7150_events,
+               .num_event_specs = ARRAY_SIZE(ad7150_events),
        },
 };
 
@@ -541,10 +576,10 @@ static const struct iio_info ad7150_info = {
        .event_attrs = &ad7150_event_attribute_group,
        .driver_module = THIS_MODULE,
        .read_raw = &ad7150_read_raw,
-       .read_event_config = &ad7150_read_event_config,
-       .write_event_config = &ad7150_write_event_config,
-       .read_event_value = &ad7150_read_event_value,
-       .write_event_value = &ad7150_write_event_value,
+       .read_event_config_new = &ad7150_read_event_config,
+       .write_event_config_new = &ad7150_write_event_config,
+       .read_event_value_new = &ad7150_read_event_value,
+       .write_event_value_new = &ad7150_write_event_value,
 };
 
 /*
index 75a533bce0217739354bfe1dad6cd1ed5e483940..862d68d99630c7249db561ff126d9011a3015052 100644 (file)
@@ -656,20 +656,21 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
                switch (chan->type) {
                case IIO_CAPACITANCE:
                        /* 8.192pf / 2^24 */
-                       *val2 = 488;
                        *val =  0;
+                       *val2 = 488;
+                       ret = IIO_VAL_INT_PLUS_NANO;
                        break;
                case IIO_VOLTAGE:
                        /* 1170mV / 2^23 */
-                       *val2 = 139475;
-                       *val =  0;
+                       *val = 1170;
+                       *val2 = 23;
+                       ret = IIO_VAL_FRACTIONAL_LOG2;
                        break;
                default:
-                       ret =  -EINVAL;
-                       goto out;
+                       ret = -EINVAL;
+                       break;
                }
 
-               ret = IIO_VAL_INT_PLUS_NANO;
                break;
        default:
                ret = -EINVAL;
index 69e90e9e60eaa9642075a5402655bf3e94d03401..a4aeee6ffdf2a6248e095f74d00397376f4105ab 100644 (file)
@@ -94,11 +94,9 @@ static int ad5930_probe(struct spi_device *spi)
        struct iio_dev *idev;
        int ret = 0;
 
-       idev = iio_device_alloc(sizeof(*st));
-       if (idev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!idev)
+               return -ENOMEM;
        spi_set_drvdata(spi, idev);
        st = iio_priv(idev);
 
@@ -110,24 +108,18 @@ static int ad5930_probe(struct spi_device *spi)
 
        ret = iio_device_register(idev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        spi->max_speed_hz = 2000000;
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 16;
        spi_setup(spi);
 
        return 0;
-
-error_free_dev:
-       iio_device_free(idev);
-error_ret:
-       return ret;
 }
 
 static int ad5930_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index 4e18380c514103a40ce01a21640697b385dd2707..c7d0307c8e76110044bf37580f35e963fc46c4da 100644 (file)
@@ -81,9 +81,9 @@ static ssize_t ad9832_write(struct device *dev,
        struct ad9832_state *st = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       unsigned long val;
 
-       ret = strict_strtoul(buf, 10, &val);
+       ret = kstrtoul(buf, 10, &val);
        if (ret)
                goto error_ret;
 
@@ -214,14 +214,14 @@ static int ad9832_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
-       reg = regulator_get(&spi->dev, "vcc");
+       reg = devm_regulator_get(&spi->dev, "vcc");
        if (!IS_ERR(reg)) {
                ret = regulator_enable(reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
        }
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL) {
                ret = -ENOMEM;
                goto error_disable_reg;
@@ -279,47 +279,42 @@ static int ad9832_probe(struct spi_device *spi)
        ret = spi_sync(st->spi, &st->msg);
        if (ret) {
                dev_err(&spi->dev, "device init failed\n");
-               goto error_free_device;
+               goto error_disable_reg;
        }
 
        ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        return 0;
 
-error_free_device:
-       iio_device_free(indio_dev);
 error_disable_reg:
        if (!IS_ERR(reg))
                regulator_disable(reg);
-error_put_reg:
-       if (!IS_ERR(reg))
-               regulator_put(reg);
 
        return ret;
 }
@@ -330,11 +325,8 @@ static int ad9832_remove(struct spi_device *spi)
        struct ad9832_state *st = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 5cba3c01f41720f57148bfe994263b17e18f71e9..86cda617609330d6183bbaea05bae90f4599b152 100644 (file)
@@ -70,9 +70,9 @@ static ssize_t ad9834_write(struct device *dev,
        struct ad9834_state *st = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       unsigned long val;
 
-       ret = strict_strtoul(buf, 10, &val);
+       ret = kstrtoul(buf, 10, &val);
        if (ret)
                goto error_ret;
 
@@ -327,14 +327,14 @@ static int ad9834_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
-       reg = regulator_get(&spi->dev, "vcc");
+       reg = devm_regulator_get(&spi->dev, "vcc");
        if (!IS_ERR(reg)) {
                ret = regulator_enable(reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
        }
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL) {
                ret = -ENOMEM;
                goto error_disable_reg;
@@ -388,39 +388,35 @@ static int ad9834_probe(struct spi_device *spi)
        ret = spi_sync(st->spi, &st->msg);
        if (ret) {
                dev_err(&spi->dev, "device init failed\n");
-               goto error_free_device;
+               goto error_disable_reg;
        }
 
        ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_device;
+               goto error_disable_reg;
 
        return 0;
 
-error_free_device:
-       iio_device_free(indio_dev);
 error_disable_reg:
        if (!IS_ERR(reg))
                regulator_disable(reg);
-error_put_reg:
-       if (!IS_ERR(reg))
-               regulator_put(reg);
+
        return ret;
 }
 
@@ -430,11 +426,8 @@ static int ad9834_remove(struct spi_device *spi)
        struct ad9834_state *st = iio_priv(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 01a8a93031f54887d76961afe781f504bd65d8d8..af877ff680e9eda37711181842327e93ade39f7f 100644 (file)
@@ -80,11 +80,9 @@ static int ad9850_probe(struct spi_device *spi)
        struct iio_dev *idev;
        int ret = 0;
 
-       idev = iio_device_alloc(sizeof(*st));
-       if (idev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!idev)
+               return -ENOMEM;
        spi_set_drvdata(spi, idev);
        st = iio_priv(idev);
        mutex_init(&st->lock);
@@ -96,24 +94,18 @@ static int ad9850_probe(struct spi_device *spi)
 
        ret = iio_device_register(idev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        spi->max_speed_hz = 2000000;
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 16;
        spi_setup(spi);
 
        return 0;
-
-error_free_dev:
-       iio_device_free(idev);
-error_ret:
-       return ret;
 }
 
 static int ad9850_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index 1344031232bca7cb2c0ce93e3c11a427d9a136e0..11e4367375d20cd18fd25177f2372b254f6edf65 100644 (file)
@@ -67,7 +67,6 @@ static ssize_t ad9852_set_parameter(struct device *dev,
                                        const char *buf,
                                        size_t len)
 {
-       struct spi_message msg;
        struct spi_transfer xfer;
        int ret;
        struct ad9852_config *config = (struct ad9852_config *)buf;
@@ -78,99 +77,77 @@ static ssize_t ad9852_set_parameter(struct device *dev,
        xfer.tx_buf = &config->phajst0[0];
        mutex_lock(&st->lock);
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 3;
        xfer.tx_buf = &config->phajst1[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 6;
        xfer.tx_buf = &config->fretun1[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 6;
        xfer.tx_buf = &config->fretun2[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 6;
        xfer.tx_buf = &config->dltafre[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->updtclk[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 4;
        xfer.tx_buf = &config->ramprat[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->control[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 3;
        xfer.tx_buf = &config->outpskm[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 2;
        xfer.tx_buf = &config->outpskr[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 3;
        xfer.tx_buf = &config->daccntl[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 error_ret:
@@ -229,11 +206,9 @@ static int ad9852_probe(struct spi_device *spi)
        struct iio_dev *idev;
        int ret = 0;
 
-       idev = iio_device_alloc(sizeof(*st));
-       if (idev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!idev)
+               return -ENOMEM;
        st = iio_priv(idev);
        spi_set_drvdata(spi, idev);
        mutex_init(&st->lock);
@@ -245,7 +220,7 @@ static int ad9852_probe(struct spi_device *spi)
 
        ret = iio_device_register(idev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        spi->max_speed_hz = 2000000;
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 8;
@@ -253,18 +228,11 @@ static int ad9852_probe(struct spi_device *spi)
        ad9852_init(st);
 
        return 0;
-
-error_free_dev:
-       iio_device_free(idev);
-
-error_ret:
-       return ret;
 }
 
 static int ad9852_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index e48f874c1fc2a8c1c05dcfbb8312d95f2155c9f9..755e0482681ab62e066aa919dcb96bfb157c8d12 100644 (file)
@@ -119,7 +119,6 @@ static ssize_t ad9910_set_parameter(struct device *dev,
                                        const char *buf,
                                        size_t len)
 {
-       struct spi_message msg;
        struct spi_transfer xfer;
        int ret;
        struct ad9910_config *config = (struct ad9910_config *)buf;
@@ -130,152 +129,118 @@ static ssize_t ad9910_set_parameter(struct device *dev,
        xfer.tx_buf = &config->auxdac[0];
        mutex_lock(&st->lock);
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->ioupd[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->ftw[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 3;
        xfer.tx_buf = &config->pow[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->asf[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->multc[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->dig_rampl[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->dig_ramps[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->dig_rampr[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep0[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep1[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep2[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep3[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep4[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep5[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep6[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 9;
        xfer.tx_buf = &config->sin_tonep7[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 error_ret:
@@ -288,7 +253,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0);
 
 static void ad9910_init(struct ad9910_state *st)
 {
-       struct spi_message msg;
        struct spi_transfer xfer;
        int ret;
        u8 cfr[5];
@@ -304,9 +268,7 @@ static void ad9910_init(struct ad9910_state *st)
        xfer.len = 5;
        xfer.tx_buf = &cfr;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
@@ -319,9 +281,7 @@ static void ad9910_init(struct ad9910_state *st)
        xfer.len = 5;
        xfer.tx_buf = &cfr;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
@@ -334,9 +294,7 @@ static void ad9910_init(struct ad9910_state *st)
        xfer.len = 5;
        xfer.tx_buf = &cfr;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
@@ -367,11 +325,9 @@ static int ad9910_probe(struct spi_device *spi)
        struct iio_dev *idev;
        int ret = 0;
 
-       idev = iio_device_alloc(sizeof(*st));
-       if (idev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!idev)
+               return -ENOMEM;
        spi_set_drvdata(spi, idev);
        st = iio_priv(idev);
        mutex_init(&st->lock);
@@ -383,24 +339,18 @@ static int ad9910_probe(struct spi_device *spi)
 
        ret = iio_device_register(idev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        spi->max_speed_hz = 2000000;
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 8;
        spi_setup(spi);
        ad9910_init(st);
        return 0;
-
-error_free_dev:
-       iio_device_free(idev);
-error_ret:
-       return ret;
 }
 
 static int ad9910_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index 8234e3c915c441ffb6291d22a0ae50c6cbb6cd72..5e8990a0210bf1d297d4eb8134c532fc17ff78fb 100644 (file)
@@ -60,7 +60,6 @@ static ssize_t ad9951_set_parameter(struct device *dev,
                                        const char *buf,
                                        size_t len)
 {
-       struct spi_message msg;
        struct spi_transfer xfer;
        int ret;
        struct ad9951_config *config = (struct ad9951_config *)buf;
@@ -71,36 +70,28 @@ static ssize_t ad9951_set_parameter(struct device *dev,
        xfer.tx_buf = &config->asf[0];
        mutex_lock(&st->lock);
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 2;
        xfer.tx_buf = &config->arr[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 5;
        xfer.tx_buf = &config->ftw0[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
        xfer.len = 3;
        xfer.tx_buf = &config->ftw1[0];
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 error_ret:
@@ -113,7 +104,6 @@ static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0);
 
 static void ad9951_init(struct ad9951_state *st)
 {
-       struct spi_message msg;
        struct spi_transfer xfer;
        int ret;
        u8 cfr[5];
@@ -129,9 +119,7 @@ static void ad9951_init(struct ad9951_state *st)
        xfer.len = 5;
        xfer.tx_buf = &cfr;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
@@ -143,9 +131,7 @@ static void ad9951_init(struct ad9951_state *st)
        xfer.len = 4;
        xfer.tx_buf = &cfr;
 
-       spi_message_init(&msg);
-       spi_message_add_tail(&xfer, &msg);
-       ret = spi_sync(st->sdev, &msg);
+       ret = spi_sync_transfer(st->sdev, &xfer, 1);
        if (ret)
                goto error_ret;
 
@@ -176,11 +162,9 @@ static int ad9951_probe(struct spi_device *spi)
        struct iio_dev *idev;
        int ret = 0;
 
-       idev = iio_device_alloc(sizeof(*st));
-       if (idev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!idev)
+               return -ENOMEM;
        spi_set_drvdata(spi, idev);
        st = iio_priv(idev);
        mutex_init(&st->lock);
@@ -193,25 +177,18 @@ static int ad9951_probe(struct spi_device *spi)
 
        ret = iio_device_register(idev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        spi->max_speed_hz = 2000000;
        spi->mode = SPI_MODE_3;
        spi->bits_per_word = 8;
        spi_setup(spi);
        ad9951_init(st);
        return 0;
-
-error_free_dev:
-       iio_device_free(idev);
-
-error_ret:
-       return ret;
 }
 
 static int ad9951_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index 0e8e02a3cf5bb1b933106c7c8cff50467f923568..1fac9894b18c2fbf2e40ad249ad66ae856ee6862 100644 (file)
@@ -57,6 +57,20 @@ static const struct iio_dummy_accel_calibscale dummy_scales[] = {
        { 733, 13, 0x9 }, /* 733.000013 */
 };
 
+#ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
+
+/*
+ * simple event - triggered when value rises above
+ * a threshold
+ */
+static const struct iio_event_spec iio_dummy_event = {
+       .type = IIO_EV_TYPE_THRESH,
+       .dir = IIO_EV_DIR_RISING,
+       .mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
+};
+
+#endif
+
 /*
  * iio_dummy_channels - Description of available channels
  *
@@ -90,6 +104,11 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
                 * when converting to standard units (microvolts)
                 */
                BIT(IIO_CHAN_INFO_SCALE),
+               /*
+                * sampling_frequency
+                * The frequency in Hz at which the channels are sampled
+                */
+               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
                /* The ordering of elements in the buffer via an enum */
                .scan_index = voltage0,
                .scan_type = { /* Description of storage in buffer */
@@ -99,12 +118,8 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
                        .shift = 0, /* zero shift */
                },
 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-               /*
-                * simple event - triggered when value rises above
-                * a threshold
-                */
-               .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH,
-                                        IIO_EV_DIR_RISING),
+               .event_spec = &iio_dummy_event,
+               .num_event_specs = 1,
 #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
        },
        /* Differential ADC channel in_voltage1-voltage2_raw etc*/
@@ -130,6 +145,10 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
                 * input channels of type IIO_VOLTAGE.
                 */
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+               /*
+                * sampling_frequency
+                * The frequency in Hz at which the channels are sampled
+                */
                .scan_index = diffvoltage1m2,
                .scan_type = { /* Description of storage in buffer */
                        .sign = 's', /* signed */
@@ -147,6 +166,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
                .channel2 = 4,
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
                .scan_index = diffvoltage3m4,
                .scan_type = {
                        .sign = 's',
@@ -173,6 +193,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
                 */
                BIT(IIO_CHAN_INFO_CALIBSCALE) |
                BIT(IIO_CHAN_INFO_CALIBBIAS),
+               .info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
                .scan_index = accelx,
                .scan_type = { /* Description of storage in buffer */
                        .sign = 's', /* signed */
@@ -272,6 +293,11 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
                *val2 = st->accel_calibscale->val2;
                ret = IIO_VAL_INT_PLUS_MICRO;
                break;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *val = 3;
+               *val2 = 33;
+               ret = IIO_VAL_INT_PLUS_NANO;
+               break;
        default:
                break;
        }
@@ -344,10 +370,10 @@ static const struct iio_info iio_dummy_info = {
        .read_raw = &iio_dummy_read_raw,
        .write_raw = &iio_dummy_write_raw,
 #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
-       .read_event_config = &iio_simple_dummy_read_event_config,
-       .write_event_config = &iio_simple_dummy_write_event_config,
-       .read_event_value = &iio_simple_dummy_read_event_value,
-       .write_event_value = &iio_simple_dummy_write_event_value,
+       .read_event_config_new = &iio_simple_dummy_read_event_config,
+       .write_event_config_new = &iio_simple_dummy_write_event_config,
+       .read_event_value_new = &iio_simple_dummy_read_event_value,
+       .write_event_value_new = &iio_simple_dummy_write_event_value,
 #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
 };
 
@@ -454,7 +480,8 @@ static int iio_dummy_probe(int index)
         * buffer, but avoid the output channel being registered by reducing the
         * number of channels by 1.
         */
-       ret = iio_simple_dummy_configure_buffer(indio_dev, iio_dummy_channels, 5);
+       ret = iio_simple_dummy_configure_buffer(indio_dev,
+                                               iio_dummy_channels, 5);
        if (ret < 0)
                goto error_unregister_events;
 
index c9e8702caca41890ce5f9f6e14b91ea07f0a4329..b126196cdf3d99562bd855496b18a9dc2cafa1f3 100644 (file)
@@ -45,19 +45,29 @@ struct iio_dummy_state {
 struct iio_dev;
 
 int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
-                                      u64 event_code);
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir);
 
 int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
-                                       u64 event_code,
+                                       const struct iio_chan_spec *chan,
+                                       enum iio_event_type type,
+                                       enum iio_event_direction dir,
                                        int state);
 
 int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
-                                     u64 event_code,
-                                     int *val);
+                                     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);
 
 int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
-                                      u64 event_code,
-                                      int val);
+                                      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);
 
 int iio_simple_dummy_events_register(struct iio_dev *indio_dev);
 int iio_simple_dummy_events_unregister(struct iio_dev *indio_dev);
index 72f400c3cbcbbdc88391a02ae14cb87fc589d2da..46c134b2a5d101a4a257b1948b4af8ee90911ace 100644 (file)
@@ -82,11 +82,8 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
                        len += 2;
                }
        }
-       /* Store the timestamp at an 8 byte aligned offset */
-       if (indio_dev->scan_timestamp)
-               *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
-                       = iio_get_time_ns();
-       iio_push_to_buffers(indio_dev, (u8 *)data);
+
+       iio_push_to_buffers_with_timestamp(indio_dev, data, iio_get_time_ns());
 
        kfree(data);
 
@@ -101,14 +98,6 @@ done:
 }
 
 static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
-       /*
-        * iio_sw_buffer_preenable:
-        * Generic function for equal sized ring elements + 64 bit timestamp
-        * Assumes that any combination of channels can be enabled.
-        * Typically replaced to implement restrictions on what combinations
-        * can be captured (hardware scan modes).
-        */
-       .preenable = &iio_sw_buffer_preenable,
        /*
         * iio_triggered_buffer_postenable:
         * Generic function that simply attaches the pollfunc to the trigger.
@@ -138,7 +127,7 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
                goto error_ret;
        }
 
-       indio_dev->buffer = buffer;
+       iio_device_attach_buffer(indio_dev, buffer);
 
        /* Enable timestamps by default */
        buffer->scan_timestamp = true;
index 317b77465db42261a64f82a26e72fbcef7b1fc7e..812ebd05a7fe889c7437da2c89697de06b9e2882 100644 (file)
 /**
  * iio_simple_dummy_read_event_config() - is event enabled?
  * @indio_dev: the device instance data
- * @event_code: event code of the event being queried
+ * @chan: channel for the event whose state is being queried
+ * @type: type of the event whose state is being queried
+ * @dir: direction of the vent whose state is being queried
  *
  * This function would normally query the relevant registers or a cache to
  * discover if the event generation is enabled on the device.
  */
 int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
-                                      u64 event_code)
+                                      const struct iio_chan_spec *chan,
+                                      enum iio_event_type type,
+                                      enum iio_event_direction dir)
 {
        struct iio_dummy_state *st = iio_priv(indio_dev);
 
@@ -39,7 +43,9 @@ int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
 /**
  * iio_simple_dummy_write_event_config() - set whether event is enabled
  * @indio_dev: the device instance data
- * @event_code: event code of event being enabled/disabled
+ * @chan: channel for the event whose state is being set
+ * @type: type of the event whose state is being set
+ * @dir: direction of the vent whose state is being set
  * @state: whether to enable or disable the device.
  *
  * This function would normally set the relevant registers on the devices
@@ -47,7 +53,9 @@ int iio_simple_dummy_read_event_config(struct iio_dev *indio_dev,
  * value.
  */
 int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
-                                       u64 event_code,
+                                       const struct iio_chan_spec *chan,
+                                       enum iio_event_type type,
+                                       enum iio_event_direction dir,
                                        int state)
 {
        struct iio_dummy_state *st = iio_priv(indio_dev);
@@ -56,12 +64,11 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
         *  Deliberately over the top code splitting to illustrate
         * how this is done when multiple events exist.
         */
-       switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
+       switch (chan->type) {
        case IIO_VOLTAGE:
-               switch (IIO_EVENT_CODE_EXTRACT_TYPE(event_code)) {
+               switch (type) {
                case IIO_EV_TYPE_THRESH:
-                       if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
-                           IIO_EV_DIR_RISING)
+                       if (dir == IIO_EV_DIR_RISING)
                                st->event_en = state;
                        else
                                return -EINVAL;
@@ -79,7 +86,10 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
 /**
  * iio_simple_dummy_read_event_value() - get value associated with event
  * @indio_dev: device instance specific data
- * @event_code: event code for the event whose value is being queried
+ * @chan: channel for the event whose value is being read
+ * @type: type of the event whose value is being read
+ * @dir: direction of the vent whose value is being read
+ * @info: info type of the event whose value is being read
  * @val: value for the event code.
  *
  * Many devices provide a large set of events of which only a subset may
@@ -89,25 +99,34 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
  * the enabled event is changed.
  */
 int iio_simple_dummy_read_event_value(struct iio_dev *indio_dev,
-                                     u64 event_code,
-                                     int *val)
+                                     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 iio_dummy_state *st = iio_priv(indio_dev);
 
        *val = st->event_val;
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
 /**
  * iio_simple_dummy_write_event_value() - set value associate with event
  * @indio_dev: device instance specific data
- * @event_code: event code for the event whose value is being set
+ * @chan: channel for the event whose value is being set
+ * @type: type of the event whose value is being set
+ * @dir: direction of the vent whose value is being set
+ * @info: info type of the event whose value is being set
  * @val: the value to be set.
  */
 int iio_simple_dummy_write_event_value(struct iio_dev *indio_dev,
-                                      u64 event_code,
-                                      int val)
+                                      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 iio_dummy_state *st = iio_priv(indio_dev);
 
index 6330af656a0f536d6a56580a5503eac75bdd3e53..0a4298b744e6e686f8bdef9175d06666c1b5cf49 100644 (file)
@@ -323,10 +323,10 @@ static ssize_t ad5933_store_frequency(struct device *dev,
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ad5933_state *st = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       long val;
+       unsigned long val;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &val);
+       ret = kstrtoul(buf, 10, &val);
        if (ret)
                return ret;
 
@@ -400,12 +400,12 @@ static ssize_t ad5933_store(struct device *dev,
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ad5933_state *st = iio_priv(indio_dev);
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       long val;
+       u16 val;
        int i, ret = 0;
        unsigned short dat;
 
        if (this_attr->address != AD5933_IN_PGA_GAIN) {
-               ret = strict_strtol(buf, 10, &val);
+               ret = kstrtou16(buf, 10, &val);
                if (ret)
                        return ret;
        }
@@ -434,7 +434,7 @@ static ssize_t ad5933_store(struct device *dev,
                ret = ad5933_cmd(st, 0);
                break;
        case AD5933_OUT_SETTLING_CYCLES:
-               val = clamp(val, 0L, 0x7FFL);
+               val = clamp(val, (u16)0, (u16)0x7FF);
                st->settling_cycles = val;
 
                /* 2x, 4x handling, see datasheet */
@@ -448,7 +448,7 @@ static ssize_t ad5933_store(struct device *dev,
                                AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat);
                break;
        case AD5933_FREQ_POINTS:
-               val = clamp(val, 0L, 511L);
+               val = clamp(val, (u16)0, (u16)511);
                st->freq_points = val;
 
                dat = cpu_to_be16(val);
@@ -574,10 +574,6 @@ static int ad5933_ring_preenable(struct iio_dev *indio_dev)
        if (bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
                return -EINVAL;
 
-       ret = iio_sw_buffer_preenable(indio_dev);
-       if (ret < 0)
-               return ret;
-
        ret = ad5933_reset(st);
        if (ret < 0)
                return ret;
@@ -630,10 +626,14 @@ static const struct iio_buffer_setup_ops ad5933_ring_setup_ops = {
 
 static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-       indio_dev->buffer = iio_kfifo_allocate(indio_dev);
-       if (!indio_dev->buffer)
+       struct iio_buffer *buffer;
+
+       buffer = iio_kfifo_allocate(indio_dev);
+       if (buffer)
                return -ENOMEM;
 
+       iio_device_attach_buffer(indio_dev, buffer);
+
        /* Ring buffer functions - here trigger setup related */
        indio_dev->setup_ops = &ad5933_ring_setup_ops;
 
@@ -676,7 +676,7 @@ static void ad5933_work(struct work_struct *work)
                } else {
                        buf[0] = be16_to_cpu(buf[0]);
                }
-               iio_push_to_buffers(indio_dev, (u8 *)buf);
+               iio_push_to_buffers(indio_dev, buf);
        } else {
                /* no data available - try again later */
                schedule_delayed_work(&st->work, st->poll_time_jiffies);
@@ -703,7 +703,9 @@ static int ad5933_probe(struct i2c_client *client,
        int ret, voltage_uv = 0;
        struct ad5933_platform_data *pdata = client->dev.platform_data;
        struct ad5933_state *st;
-       struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+       struct iio_dev *indio_dev;
+
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
 
@@ -716,11 +718,11 @@ static int ad5933_probe(struct i2c_client *client,
        else
                st->pdata = pdata;
 
-       st->reg = regulator_get(&client->dev, "vcc");
+       st->reg = devm_regulator_get(&client->dev, "vcc");
        if (!IS_ERR(st->reg)) {
                ret = regulator_enable(st->reg);
                if (ret)
-                       goto error_put_reg;
+                       return ret;
                voltage_uv = regulator_get_voltage(st->reg);
        }
 
@@ -778,11 +780,6 @@ error_unreg_ring:
 error_disable_reg:
        if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-error_put_reg:
-       if (!IS_ERR(st->reg))
-               regulator_put(st->reg);
-
-       iio_device_free(indio_dev);
 
        return ret;
 }
@@ -795,11 +792,8 @@ static int ad5933_remove(struct i2c_client *client)
        iio_device_unregister(indio_dev);
        iio_buffer_unregister(indio_dev);
        iio_kfifo_free(indio_dev->buffer);
-       if (!IS_ERR(st->reg)) {
+       if (!IS_ERR(st->reg))
                regulator_disable(st->reg);
-               regulator_put(st->reg);
-       }
-       iio_device_free(indio_dev);
 
        return 0;
 }
index e4998e4d4434b2af9365aacc1a8c4137a4c70544..488e690388c948dc3cda08afdc334cebc15966ef 100644 (file)
@@ -240,7 +240,7 @@ static ssize_t store_range(struct device *dev,
        unsigned long lval;
        unsigned int new_range;
 
-       if (strict_strtoul(buf, 10, &lval))
+       if (kstrtoul(buf, 10, &lval))
                return -EINVAL;
 
        if (!(lval == 1000UL || lval == 4000UL ||
@@ -279,18 +279,18 @@ static ssize_t store_resolution(struct device *dev,
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct isl29018_chip *chip = iio_priv(indio_dev);
        int status;
-       unsigned long lval;
+       unsigned int val;
        unsigned int new_adc_bit;
 
-       if (strict_strtoul(buf, 10, &lval))
+       if (kstrtouint(buf, 10, &val))
                return -EINVAL;
-       if (!(lval == 4 || lval == 8 || lval == 12 || lval == 16)) {
+       if (!(val == 4 || val == 8 || val == 12 || val == 16)) {
                dev_err(dev, "The resolution is not supported\n");
                return -EINVAL;
        }
 
        mutex_lock(&chip->lock);
-       status = isl29018_set_resolution(chip, lval, &new_adc_bit);
+       status = isl29018_set_resolution(chip, val, &new_adc_bit);
        if (status < 0) {
                mutex_unlock(&chip->lock);
                dev_err(dev, "Error in setting resolution\n");
@@ -319,11 +319,11 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct isl29018_chip *chip = iio_priv(indio_dev);
-       unsigned long lval;
+       int val;
 
-       if (strict_strtoul(buf, 10, &lval))
+       if (kstrtoint(buf, 10, &val))
                return -EINVAL;
-       if (!(lval == 0UL || lval == 1UL)) {
+       if (!(val == 0 || val == 1)) {
                dev_err(dev, "The mode is not supported\n");
                return -EINVAL;
        }
@@ -331,7 +331,7 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
        /* get the  "proximity scheme" i.e. if the chip does on chip
        infrared suppression (1 means perform on chip suppression) */
        mutex_lock(&chip->lock);
-       chip->prox_scheme = (int)lval;
+       chip->prox_scheme = val;
        mutex_unlock(&chip->lock);
 
        return count;
index b377dd3b76ad3a2eea33e34025923859bb1b477b..f8c659568c384f1884e74757df2981deb508b0ab 100644 (file)
@@ -493,9 +493,9 @@ static ssize_t taos_power_state_store(struct device *dev,
        struct device_attribute *attr, const char *buf, size_t len)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        if (value == 0)
@@ -536,9 +536,9 @@ static ssize_t taos_gain_store(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tsl2583_chip *chip = iio_priv(indio_dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        switch (value) {
@@ -582,9 +582,9 @@ static ssize_t taos_als_time_store(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tsl2583_chip *chip = iio_priv(indio_dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        if ((value < 50) || (value > 650))
@@ -619,9 +619,9 @@ static ssize_t taos_als_trim_store(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tsl2583_chip *chip = iio_priv(indio_dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        if (value)
@@ -644,9 +644,9 @@ static ssize_t taos_als_cal_target_store(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct tsl2583_chip *chip = iio_priv(indio_dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        if (value)
@@ -671,9 +671,9 @@ static ssize_t taos_do_calibrate(struct device *dev,
        struct device_attribute *attr, const char *buf, size_t len)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       unsigned long value;
+       int value;
 
-       if (strict_strtoul(buf, 0, &value))
+       if (kstrtoint(buf, 0, &value))
                return -EINVAL;
 
        if (value == 1)
@@ -815,12 +815,9 @@ static int taos_probe(struct i2c_client *clientp,
                return -EOPNOTSUPP;
        }
 
-       indio_dev = iio_device_alloc(sizeof(*chip));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               dev_err(&clientp->dev, "iio allocation failed\n");
-               goto fail1;
-       }
+       indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
+       if (!indio_dev)
+               return -ENOMEM;
        chip = iio_priv(indio_dev);
        chip->client = clientp;
        i2c_set_clientdata(clientp, indio_dev);
@@ -835,14 +832,14 @@ static int taos_probe(struct i2c_client *clientp,
                if (ret < 0) {
                        dev_err(&clientp->dev, "i2c_smbus_write_bytes() to cmd "
                                "reg failed in taos_probe(), err = %d\n", ret);
-                       goto fail2;
+                       return ret;
                }
                ret = i2c_smbus_read_byte(clientp);
                if (ret < 0) {
                        dev_err(&clientp->dev, "i2c_smbus_read_byte from "
                                "reg failed in taos_probe(), err = %d\n", ret);
 
-                       goto fail2;
+                       return ret;
                }
                buf[i] = ret;
        }
@@ -850,14 +847,14 @@ static int taos_probe(struct i2c_client *clientp,
        if (!taos_tsl258x_device(buf)) {
                dev_info(&clientp->dev, "i2c device found but does not match "
                        "expected id in taos_probe()\n");
-               goto fail2;
+               return -EINVAL;
        }
 
        ret = i2c_smbus_write_byte(clientp, (TSL258X_CMD_REG | TSL258X_CNTRL));
        if (ret < 0) {
                dev_err(&clientp->dev, "i2c_smbus_write_byte() to cmd reg "
                        "failed in taos_probe(), err = %d\n", ret);
-               goto fail2;
+               return ret;
        }
 
        indio_dev->info = &tsl2583_info;
@@ -867,7 +864,7 @@ static int taos_probe(struct i2c_client *clientp,
        ret = iio_device_register(indio_dev);
        if (ret) {
                dev_err(&clientp->dev, "iio registration failed\n");
-               goto fail2;
+               return ret;
        }
 
        /* Load up the V2 defaults (these are hard coded defaults for now) */
@@ -878,10 +875,6 @@ static int taos_probe(struct i2c_client *clientp,
 
        dev_info(&clientp->dev, "Light sensor found.\n");
        return 0;
-fail1:
-       iio_device_free(indio_dev);
-fail2:
-       return ret;
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -926,7 +919,6 @@ static SIMPLE_DEV_PM_OPS(taos_pm_ops, taos_suspend, taos_resume);
 static int taos_remove(struct i2c_client *client)
 {
        iio_device_unregister(i2c_get_clientdata(client));
-       iio_device_free(i2c_get_clientdata(client));
 
        return 0;
 }
index c99f890cc6c65ae9ea13a9aafa8c8258e21e3cb8..18805029d2a915a72cbbe1c28579954a57aac679 100644 (file)
 #define TSL2X7X_mA13                   0xD0
 #define TSL2X7X_MAX_TIMER_CNT          (0xFF)
 
-/*Common device IIO EventMask */
-#define TSL2X7X_EVENT_MASK \
-               (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) | \
-               IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)),
-
 #define TSL2X7X_MIN_ITIME 3
 
 /* TAOS txx2x7x Device family members */
@@ -550,7 +545,7 @@ prox_poll_err:
 static void tsl2x7x_defaults(struct tsl2X7X_chip *chip)
 {
        /* If Operational settings defined elsewhere.. */
-       if (chip->pdata && chip->pdata->platform_default_settings != 0)
+       if (chip->pdata && chip->pdata->platform_default_settings)
                memcpy(&(chip->tsl2x7x_settings),
                        chip->pdata->platform_default_settings,
                        sizeof(tsl2x7x_default_settings));
@@ -951,7 +946,6 @@ static ssize_t tsl2x7x_gain_available_show(struct device *dev,
        case tsl2771:
        case tmd2771:
                return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128");
-       break;
        }
 
        return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
@@ -1223,12 +1217,14 @@ static ssize_t tsl2x7x_do_prox_calibrate(struct device *dev,
 }
 
 static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
-                                        u64 event_code)
+                                        const struct iio_chan_spec *chan,
+                                        enum iio_event_type type,
+                                        enum iio_event_direction dir)
 {
        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
        int ret;
 
-       if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY)
+       if (chan->type == IIO_INTENSITY)
                ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x10);
        else
                ret = !!(chip->tsl2x7x_settings.interrupts_en & 0x20);
@@ -1237,12 +1233,14 @@ static int tsl2x7x_read_interrupt_config(struct iio_dev *indio_dev,
 }
 
 static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
-                                         u64 event_code,
+                                         const struct iio_chan_spec *chan,
+                                         enum iio_event_type type,
+                                         enum iio_event_direction dir,
                                          int val)
 {
        struct tsl2X7X_chip *chip = iio_priv(indio_dev);
 
-       if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
+       if (chan->type == IIO_INTENSITY) {
                if (val)
                        chip->tsl2x7x_settings.interrupts_en |= 0x10;
                else
@@ -1260,13 +1258,16 @@ static int tsl2x7x_write_interrupt_config(struct iio_dev *indio_dev,
 }
 
 static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
-                                 u64 event_code,
-                                 int val)
+                               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 tsl2X7X_chip *chip = iio_priv(indio_dev);
 
-       if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
-               switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+       if (chan->type == IIO_INTENSITY) {
+               switch (dir) {
                case IIO_EV_DIR_RISING:
                        chip->tsl2x7x_settings.als_thresh_high = val;
                        break;
@@ -1277,7 +1278,7 @@ static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
                        return -EINVAL;
                }
        } else {
-               switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+               switch (dir) {
                case IIO_EV_DIR_RISING:
                        chip->tsl2x7x_settings.prox_thres_high = val;
                        break;
@@ -1295,13 +1296,16 @@ static int tsl2x7x_write_thresh(struct iio_dev *indio_dev,
 }
 
 static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
-                              u64 event_code,
-                              int *val)
+                              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 tsl2X7X_chip *chip = iio_priv(indio_dev);
 
-       if (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code) == IIO_INTENSITY) {
-               switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+       if (chan->type == IIO_INTENSITY) {
+               switch (dir) {
                case IIO_EV_DIR_RISING:
                        *val = chip->tsl2x7x_settings.als_thresh_high;
                        break;
@@ -1312,7 +1316,7 @@ static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
                        return -EINVAL;
                }
        } else {
-               switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+               switch (dir) {
                case IIO_EV_DIR_RISING:
                        *val = chip->tsl2x7x_settings.prox_thres_high;
                        break;
@@ -1324,7 +1328,7 @@ static int tsl2x7x_read_thresh(struct iio_dev *indio_dev,
                }
        }
 
-       return 0;
+       return IIO_VAL_INT;
 }
 
 static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
@@ -1346,7 +1350,6 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
                        break;
                default:
                        return -EINVAL;
-                       break;
                }
                break;
        case IIO_CHAN_INFO_RAW:
@@ -1366,7 +1369,6 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
                        break;
                default:
                        return -EINVAL;
-                       break;
                }
                break;
        case IIO_CHAN_INFO_CALIBSCALE:
@@ -1419,7 +1421,6 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
                                case tsl2772:
                                case tmd2772:
                                        return -EINVAL;
-                               break;
                                }
                                chip->tsl2x7x_settings.als_gain = 3;
                                break;
@@ -1431,7 +1432,6 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
                                case tsl2771:
                                case tmd2771:
                                        return -EINVAL;
-                               break;
                                }
                                chip->tsl2x7x_settings.als_gain = 3;
                                break;
@@ -1508,18 +1508,15 @@ static int tsl2x7x_device_id(unsigned char *id, int target)
        case tsl2671:
        case tsl2771:
                return ((*id & 0xf0) == TRITON_ID);
-       break;
        case tmd2671:
        case tmd2771:
                return ((*id & 0xf0) == HALIBUT_ID);
-       break;
        case tsl2572:
        case tsl2672:
        case tmd2672:
        case tsl2772:
        case tmd2772:
                return ((*id & 0xf0) == SWORDFISH_ID);
-       break;
        }
 
        return -EINVAL;
@@ -1675,10 +1672,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
                .driver_module = THIS_MODULE,
                .read_raw = &tsl2x7x_read_raw,
                .write_raw = &tsl2x7x_write_raw,
-               .read_event_value = &tsl2x7x_read_thresh,
-               .write_event_value = &tsl2x7x_write_thresh,
-               .read_event_config = &tsl2x7x_read_interrupt_config,
-               .write_event_config = &tsl2x7x_write_interrupt_config,
+               .read_event_value_new = &tsl2x7x_read_thresh,
+               .write_event_value_new = &tsl2x7x_write_thresh,
+               .read_event_config_new = &tsl2x7x_read_interrupt_config,
+               .write_event_config_new = &tsl2x7x_write_interrupt_config,
        },
        [PRX] = {
                .attrs = &tsl2X7X_device_attr_group_tbl[PRX],
@@ -1686,10 +1683,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
                .driver_module = THIS_MODULE,
                .read_raw = &tsl2x7x_read_raw,
                .write_raw = &tsl2x7x_write_raw,
-               .read_event_value = &tsl2x7x_read_thresh,
-               .write_event_value = &tsl2x7x_write_thresh,
-               .read_event_config = &tsl2x7x_read_interrupt_config,
-               .write_event_config = &tsl2x7x_write_interrupt_config,
+               .read_event_value_new = &tsl2x7x_read_thresh,
+               .write_event_value_new = &tsl2x7x_write_thresh,
+               .read_event_config_new = &tsl2x7x_read_interrupt_config,
+               .write_event_config_new = &tsl2x7x_write_interrupt_config,
        },
        [ALSPRX] = {
                .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX],
@@ -1697,10 +1694,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
                .driver_module = THIS_MODULE,
                .read_raw = &tsl2x7x_read_raw,
                .write_raw = &tsl2x7x_write_raw,
-               .read_event_value = &tsl2x7x_read_thresh,
-               .write_event_value = &tsl2x7x_write_thresh,
-               .read_event_config = &tsl2x7x_read_interrupt_config,
-               .write_event_config = &tsl2x7x_write_interrupt_config,
+               .read_event_value_new = &tsl2x7x_read_thresh,
+               .write_event_value_new = &tsl2x7x_write_thresh,
+               .read_event_config_new = &tsl2x7x_read_interrupt_config,
+               .write_event_config_new = &tsl2x7x_write_interrupt_config,
        },
        [PRX2] = {
                .attrs = &tsl2X7X_device_attr_group_tbl[PRX2],
@@ -1708,10 +1705,10 @@ static const struct iio_info tsl2X7X_device_info[] = {
                .driver_module = THIS_MODULE,
                .read_raw = &tsl2x7x_read_raw,
                .write_raw = &tsl2x7x_write_raw,
-               .read_event_value = &tsl2x7x_read_thresh,
-               .write_event_value = &tsl2x7x_write_thresh,
-               .read_event_config = &tsl2x7x_read_interrupt_config,
-               .write_event_config = &tsl2x7x_write_interrupt_config,
+               .read_event_value_new = &tsl2x7x_read_thresh,
+               .write_event_value_new = &tsl2x7x_write_thresh,
+               .read_event_config_new = &tsl2x7x_read_interrupt_config,
+               .write_event_config_new = &tsl2x7x_write_interrupt_config,
        },
        [ALSPRX2] = {
                .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2],
@@ -1719,10 +1716,24 @@ static const struct iio_info tsl2X7X_device_info[] = {
                .driver_module = THIS_MODULE,
                .read_raw = &tsl2x7x_read_raw,
                .write_raw = &tsl2x7x_write_raw,
-               .read_event_value = &tsl2x7x_read_thresh,
-               .write_event_value = &tsl2x7x_write_thresh,
-               .read_event_config = &tsl2x7x_read_interrupt_config,
-               .write_event_config = &tsl2x7x_write_interrupt_config,
+               .read_event_value_new = &tsl2x7x_read_thresh,
+               .write_event_value_new = &tsl2x7x_write_thresh,
+               .read_event_config_new = &tsl2x7x_read_interrupt_config,
+               .write_event_config_new = &tsl2x7x_write_interrupt_config,
+       },
+};
+
+static const struct iio_event_spec tsl2x7x_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),
        },
 };
 
@@ -1741,7 +1752,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
                                BIT(IIO_CHAN_INFO_CALIBBIAS),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        }, {
                        .type = IIO_INTENSITY,
                        .indexed = 1,
@@ -1758,7 +1770,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .indexed = 1,
                        .channel = 0,
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        },
                },
        .chan_table_elements = 1,
@@ -1778,7 +1791,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
                                BIT(IIO_CHAN_INFO_CALIBBIAS),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        }, {
                        .type = IIO_INTENSITY,
                        .indexed = 1,
@@ -1789,7 +1803,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .indexed = 1,
                        .channel = 0,
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        },
                },
        .chan_table_elements = 4,
@@ -1803,7 +1818,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .channel = 0,
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_CALIBSCALE),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        },
                },
        .chan_table_elements = 1,
@@ -1823,7 +1839,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_CALIBSCALE) |
                                BIT(IIO_CHAN_INFO_CALIBBIAS),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        }, {
                        .type = IIO_INTENSITY,
                        .indexed = 1,
@@ -1835,7 +1852,8 @@ static const struct tsl2x7x_chip_info tsl2x7x_chip_info_tbl[] = {
                        .channel = 0,
                        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
                                BIT(IIO_CHAN_INFO_CALIBSCALE),
-                       .event_mask = TSL2X7X_EVENT_MASK
+                       .event_spec = tsl2x7x_events,
+                       .num_event_specs = ARRAY_SIZE(tsl2x7x_events),
                        },
                },
        .chan_table_elements = 4,
@@ -1851,7 +1869,7 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
        struct iio_dev *indio_dev;
        struct tsl2X7X_chip *chip;
 
-       indio_dev = iio_device_alloc(sizeof(*chip));
+       indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
        if (!indio_dev)
                return -ENOMEM;
 
@@ -1862,22 +1880,21 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
        ret = tsl2x7x_i2c_read(chip->client,
                TSL2X7X_CHIPID, &device_id);
        if (ret < 0)
-               goto fail1;
+               return ret;
 
        if ((!tsl2x7x_device_id(&device_id, id->driver_data)) ||
                (tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) {
                dev_info(&chip->client->dev,
                                "%s: i2c device found does not match expected id\n",
                                __func__);
-               ret = -EINVAL;
-               goto fail1;
+               return -EINVAL;
        }
 
        ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
        if (ret < 0) {
                dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n",
                                __func__, ret);
-               goto fail1;
+               return ret;
        }
 
        /* ALS and PROX functions can be invoked via user space poll
@@ -1899,16 +1916,17 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
        indio_dev->num_channels = chip->chip_info->chan_table_elements;
 
        if (clientp->irq) {
-               ret = request_threaded_irq(clientp->irq,
-                                          NULL,
-                                          &tsl2x7x_event_handler,
-                                          IRQF_TRIGGER_RISING | IRQF_ONESHOT,
-                                          "TSL2X7X_event",
-                                          indio_dev);
+               ret = devm_request_threaded_irq(&clientp->dev, clientp->irq,
+                                               NULL,
+                                               &tsl2x7x_event_handler,
+                                               IRQF_TRIGGER_RISING |
+                                               IRQF_ONESHOT,
+                                               "TSL2X7X_event",
+                                               indio_dev);
                if (ret) {
                        dev_err(&clientp->dev,
                                "%s: irq request failed", __func__);
-                       goto fail1;
+                       return ret;
                }
        }
 
@@ -1921,20 +1939,12 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
        if (ret) {
                dev_err(&clientp->dev,
                        "%s: iio registration failed\n", __func__);
-               goto fail2;
+               return ret;
        }
 
        dev_info(&clientp->dev, "%s Light sensor found.\n", id->name);
 
        return 0;
-
-fail2:
-       if (clientp->irq)
-               free_irq(clientp->irq, indio_dev);
-fail1:
-       iio_device_free(indio_dev);
-
-       return ret;
 }
 
 static int tsl2x7x_suspend(struct device *dev)
@@ -1980,10 +1990,6 @@ static int tsl2x7x_remove(struct i2c_client *client)
        tsl2x7x_chip_off(indio_dev);
 
        iio_device_unregister(indio_dev);
-       if (client->irq)
-               free_irq(client->irq, indio_dev);
-
-       iio_device_free(indio_dev);
 
        return 0;
 }
index c3f3f539e787e926b54f793958d8e9dac13aa6d7..99421f90d1895f6a0691d4443c457f5aac2335db 100644 (file)
 #include <linux/i2c.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
 #include <linux/delay.h>
 
 #define HMC5843_CONFIG_REG_A                   0x00
 #define HMC5843_CONFIG_REG_B                   0x01
 #define HMC5843_MODE_REG                       0x02
-#define HMC5843_DATA_OUT_X_MSB_REG             0x03
-#define HMC5843_DATA_OUT_X_LSB_REG             0x04
-#define HMC5843_DATA_OUT_Y_MSB_REG             0x05
-#define HMC5843_DATA_OUT_Y_LSB_REG             0x06
-#define HMC5843_DATA_OUT_Z_MSB_REG             0x07
-#define HMC5843_DATA_OUT_Z_LSB_REG             0x08
-/* Beware: Y and Z are exchanged on HMC5883 */
-#define HMC5883_DATA_OUT_Z_MSB_REG             0x05
-#define HMC5883_DATA_OUT_Z_LSB_REG             0x06
-#define HMC5883_DATA_OUT_Y_MSB_REG             0x07
-#define HMC5883_DATA_OUT_Y_LSB_REG             0x08
+#define HMC5843_DATA_OUT_MSB_REGS              0x03
 #define HMC5843_STATUS_REG                     0x09
+#define HMC5843_ID_REG                         0x0a
 
 enum hmc5843_ids {
        HMC5843_ID,
@@ -54,19 +48,13 @@ enum hmc5843_ids {
  */
 #define HMC5843_RANGE_GAIN_OFFSET              0x05
 #define HMC5843_RANGE_GAIN_DEFAULT             0x01
-#define HMC5843_RANGE_GAIN_MAX                 0x07
+#define HMC5843_RANGE_GAINS                    8
 
-/*
- * Device status
- */
+/* Device status */
 #define HMC5843_DATA_READY                     0x01
 #define HMC5843_DATA_OUTPUT_LOCK               0x02
-/* Does not exist on HMC5883, not used */
-#define HMC5843_VOLTAGE_REGULATOR_ENABLED      0x04
 
-/*
- * Mode register configuration
- */
+/* Mode register configuration */
 #define HMC5843_MODE_CONVERSION_CONTINUOUS     0x00
 #define HMC5843_MODE_CONVERSION_SINGLE         0x01
 #define HMC5843_MODE_IDLE                      0x02
@@ -78,79 +66,28 @@ enum hmc5843_ids {
  * HMC5883: Typical data output rate
  */
 #define HMC5843_RATE_OFFSET                    0x02
-#define HMC5843_RATE_BITMASK                   0x1C
-#define HMC5843_RATE_NOT_USED                  0x07
+#define HMC5843_RATE_DEFAULT                   0x04
+#define HMC5843_RATES                          7
 
-/*
- * Device measurement configuration
- */
+/* Device measurement configuration */
 #define HMC5843_MEAS_CONF_NORMAL               0x00
 #define HMC5843_MEAS_CONF_POSITIVE_BIAS                0x01
 #define HMC5843_MEAS_CONF_NEGATIVE_BIAS                0x02
-#define HMC5843_MEAS_CONF_NOT_USED             0x03
 #define HMC5843_MEAS_CONF_MASK                 0x03
 
-/*
- * Scaling factors: 10000000/Gain
- */
-static const int hmc5843_regval_to_nanoscale[] = {
+/* Scaling factors: 10000000/Gain */
+static const int hmc5843_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
        6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714
 };
 
-static const int hmc5883_regval_to_nanoscale[] = {
+static const int hmc5883_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
        7812, 9766, 13021, 16287, 24096, 27701, 32573, 45662
 };
 
-static const int hmc5883l_regval_to_nanoscale[] = {
+static const int hmc5883l_regval_to_nanoscale[HMC5843_RANGE_GAINS] = {
        7299, 9174, 12195, 15152, 22727, 25641, 30303, 43478
 };
 
-/*
- * From the HMC5843 datasheet:
- * Value       | Sensor input field range (Ga) | Gain (counts/milli-Gauss)
- * 0           | (+-)0.7                       | 1620
- * 1           | (+-)1.0                       | 1300
- * 2           | (+-)1.5                       | 970
- * 3           | (+-)2.0                       | 780
- * 4           | (+-)3.2                       | 530
- * 5           | (+-)3.8                       | 460
- * 6           | (+-)4.5                       | 390
- * 7           | (+-)6.5                       | 280
- *
- * From the HMC5883 datasheet:
- * Value       | Recommended sensor field range (Ga)   | Gain (counts/Gauss)
- * 0           | (+-)0.9                               | 1280
- * 1           | (+-)1.2                               | 1024
- * 2           | (+-)1.9                               | 768
- * 3           | (+-)2.5                               | 614
- * 4           | (+-)4.0                               | 415
- * 5           | (+-)4.6                               | 361
- * 6           | (+-)5.5                               | 307
- * 7           | (+-)7.9                               | 219
- *
- * From the HMC5883L datasheet:
- * Value       | Recommended sensor field range (Ga)   | Gain (LSB/Gauss)
- * 0           | (+-)0.88                              | 1370
- * 1           | (+-)1.3                               | 1090
- * 2           | (+-)1.9                               | 820
- * 3           | (+-)2.5                               | 660
- * 4           | (+-)4.0                               | 440
- * 5           | (+-)4.7                               | 390
- * 6           | (+-)5.6                               | 330
- * 7           | (+-)8.1                               | 230
- */
-static const int hmc5843_regval_to_input_field_mga[] = {
-       700, 1000, 1500, 2000, 3200, 3800, 4500, 6500
-};
-
-static const int hmc5883_regval_to_input_field_mga[] = {
-       900, 1200, 1900, 2500, 4000, 4600, 5500, 7900
-};
-
-static const int hmc5883l_regval_to_input_field_mga[] = {
-       880, 1300, 1900, 2500, 4000, 4700, 5600, 8100
-};
-
 /*
  * From the datasheet:
  * Value       | HMC5843               | HMC5883/HMC5883L
@@ -164,141 +101,94 @@ static const int hmc5883l_regval_to_input_field_mga[] = {
  * 6           | 50                    | 75
  * 7           | Not used              | Not used
  */
-static const char * const hmc5843_regval_to_sample_freq[] = {
-       "0.5", "1", "2", "5", "10", "20", "50",
+static const int hmc5843_regval_to_samp_freq[7][2] = {
+       {0, 500000}, {1, 0}, {2, 0}, {5, 0}, {10, 0}, {20, 0}, {50, 0}
 };
 
-static const char * const hmc5883_regval_to_sample_freq[] = {
-       "0.75", "1.5", "3", "7.5", "15", "30", "75",
+static const int hmc5883_regval_to_samp_freq[7][2] = {
+       {0, 750000}, {1, 500000}, {3, 0}, {7, 500000}, {15, 0}, {30, 0},
+       {75, 0}
 };
 
 /* Describe chip variants */
 struct hmc5843_chip_info {
        const struct iio_chan_spec *channels;
-       const char * const *regval_to_sample_freq;
-       const int *regval_to_input_field_mga;
+       const int (*regval_to_samp_freq)[2];
        const int *regval_to_nanoscale;
 };
 
 /* Each client has this additional data */
 struct hmc5843_data {
+       struct i2c_client *client;
        struct mutex lock;
        u8 rate;
        u8 meas_conf;
        u8 operating_mode;
        u8 range;
        const struct hmc5843_chip_info *variant;
+       __be16 buffer[8]; /* 3x 16-bit channels + padding + 64-bit timestamp */
 };
 
 /* The lower two bits contain the current conversion mode */
-static s32 hmc5843_configure(struct i2c_client *client,
-                                      u8 operating_mode)
+static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode)
 {
-       return i2c_smbus_write_byte_data(client,
-                                       HMC5843_MODE_REG,
+       int ret;
+
+       mutex_lock(&data->lock);
+       ret = i2c_smbus_write_byte_data(data->client, HMC5843_MODE_REG,
                                        operating_mode & HMC5843_MODE_MASK);
+       if (ret >= 0)
+               data->operating_mode = operating_mode;
+       mutex_unlock(&data->lock);
+
+       return ret;
 }
 
-/* Return the measurement value from the specified channel */
-static int hmc5843_read_measurement(struct iio_dev *indio_dev,
-                                   int address,
-                                   int *val)
+static int hmc5843_wait_measurement(struct hmc5843_data *data)
 {
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct hmc5843_data *data = iio_priv(indio_dev);
        s32 result;
        int tries = 150;
 
-       mutex_lock(&data->lock);
        while (tries-- > 0) {
-               result = i2c_smbus_read_byte_data(client,
+               result = i2c_smbus_read_byte_data(data->client,
                        HMC5843_STATUS_REG);
+               if (result < 0)
+                       return result;
                if (result & HMC5843_DATA_READY)
                        break;
                msleep(20);
        }
 
        if (tries < 0) {
-               dev_err(&client->dev, "data not ready\n");
-               mutex_unlock(&data->lock);
+               dev_err(&data->client->dev, "data not ready\n");
                return -EIO;
        }
 
-       result = i2c_smbus_read_word_swapped(client, address);
-       mutex_unlock(&data->lock);
-       if (result < 0)
-               return -EINVAL;
-
-       *val = sign_extend32(result, 15);
-       return IIO_VAL_INT;
-}
-
-/*
- * From the datasheet:
- * 0 - Continuous-Conversion Mode: In continuous-conversion mode, the
- *     device continuously performs conversions and places the result in
- *     the data register.
- *
- * 1 - Single-Conversion Mode : Device performs a single measurement,
- *     sets RDY high and returns to sleep mode.
- *
- * 2 - Idle Mode : Device is placed in idle mode.
- *
- * 3 - Sleep Mode : Device is placed in sleep mode.
- *
- */
-static ssize_t hmc5843_show_operating_mode(struct device *dev,
-                                       struct device_attribute *attr,
-                                       char *buf)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       return sprintf(buf, "%d\n", data->operating_mode);
+       return 0;
 }
 
-static ssize_t hmc5843_set_operating_mode(struct device *dev,
-                               struct device_attribute *attr,
-                               const char *buf,
-                               size_t count)
+/* Return the measurement value from the specified channel */
+static int hmc5843_read_measurement(struct hmc5843_data *data,
+                                   int idx, int *val)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       unsigned long operating_mode = 0;
-       s32 status;
-       int error;
+       s32 result;
+       __be16 values[3];
 
        mutex_lock(&data->lock);
-       error = kstrtoul(buf, 10, &operating_mode);
-       if (error) {
-               count = error;
-               goto exit;
-       }
-       dev_dbg(dev, "set conversion mode to %lu\n", operating_mode);
-       if (operating_mode > HMC5843_MODE_SLEEP) {
-               count = -EINVAL;
-               goto exit;
-       }
-
-       status = i2c_smbus_write_byte_data(client, this_attr->address,
-                                       operating_mode);
-       if (status) {
-               count = -EINVAL;
-               goto exit;
+       result = hmc5843_wait_measurement(data);
+       if (result < 0) {
+               mutex_unlock(&data->lock);
+               return result;
        }
-       data->operating_mode = operating_mode;
-
-exit:
+       result = i2c_smbus_read_i2c_block_data(data->client,
+               HMC5843_DATA_OUT_MSB_REGS, sizeof(values), (u8 *) values);
        mutex_unlock(&data->lock);
-       return count;
-}
+       if (result < 0)
+               return -EINVAL;
 
-static IIO_DEVICE_ATTR(operating_mode,
-                       S_IWUSR | S_IRUGO,
-                       hmc5843_show_operating_mode,
-                       hmc5843_set_operating_mode,
-                       HMC5843_MODE_REG);
+       *val = sign_extend32(be16_to_cpu(values[idx]), 15);
+       return IIO_VAL_INT;
+}
 
 /*
  * API for setting the measurement configuration to
@@ -318,23 +208,26 @@ static IIO_DEVICE_ATTR(operating_mode,
  *     and BN.
  *
  */
-static s32 hmc5843_set_meas_conf(struct i2c_client *client,
-                                     u8 meas_conf)
+static s32 hmc5843_set_meas_conf(struct hmc5843_data *data, u8 meas_conf)
 {
-       struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       u8 reg_val;
-       reg_val = (meas_conf & HMC5843_MEAS_CONF_MASK) |
-               (data->rate << HMC5843_RATE_OFFSET);
-       return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
+       int ret;
+
+       mutex_lock(&data->lock);
+       ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
+               (meas_conf & HMC5843_MEAS_CONF_MASK) |
+               (data->rate << HMC5843_RATE_OFFSET));
+       if (ret >= 0)
+               data->meas_conf = meas_conf;
+       mutex_unlock(&data->lock);
+
+       return ret;
 }
 
 static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
                                                struct device_attribute *attr,
                                                char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct hmc5843_data *data = iio_priv(indio_dev);
+       struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
        return sprintf(buf, "%d\n", data->meas_conf);
 }
 
@@ -343,29 +236,19 @@ static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
                                                const char *buf,
                                                size_t count)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct hmc5843_data *data = iio_priv(indio_dev);
+       struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
        unsigned long meas_conf = 0;
-       int error;
+       int ret;
 
-       error = kstrtoul(buf, 10, &meas_conf);
-       if (error)
-               return error;
-       if (meas_conf >= HMC5843_MEAS_CONF_NOT_USED)
+       ret = kstrtoul(buf, 10, &meas_conf);
+       if (ret)
+               return ret;
+       if (meas_conf >= HMC5843_MEAS_CONF_MASK)
                return -EINVAL;
 
-       mutex_lock(&data->lock);
-       dev_dbg(dev, "set measurement configuration to %lu\n", meas_conf);
-       if (hmc5843_set_meas_conf(client, meas_conf)) {
-               count = -EINVAL;
-               goto exit;
-       }
-       data->meas_conf = meas_conf;
+       ret = hmc5843_set_meas_conf(data, meas_conf);
 
-exit:
-       mutex_unlock(&data->lock);
-       return count;
+       return (ret < 0) ? ret : count;
 }
 
 static IIO_DEVICE_ATTR(meas_conf,
@@ -374,211 +257,221 @@ static IIO_DEVICE_ATTR(meas_conf,
                        hmc5843_set_measurement_configuration,
                        0);
 
-static ssize_t hmc5843_show_sampling_frequencies_available(struct device *dev,
-                                               struct device_attribute *attr,
-                                               char *buf)
+static ssize_t hmc5843_show_samp_freq_avail(struct device *dev,
+                               struct device_attribute *attr, char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       ssize_t total_n = 0;
+       struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
+       size_t len = 0;
        int i;
 
-       for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
-               ssize_t n = sprintf(buf, "%s ", data->variant->regval_to_sample_freq[i]);
-               buf += n;
-               total_n += n;
-       }
+       for (i = 0; i < HMC5843_RATES; i++)
+               len += scnprintf(buf + len, PAGE_SIZE - len,
+                       "%d.%d ", data->variant->regval_to_samp_freq[i][0],
+                       data->variant->regval_to_samp_freq[i][1]);
+
        /* replace trailing space by newline */
-       buf[-1] = '\n';
+       buf[len - 1] = '\n';
 
-       return total_n;
+       return len;
 }
 
-static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_sampling_frequencies_available);
+static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(hmc5843_show_samp_freq_avail);
 
-static s32 hmc5843_set_rate(struct i2c_client *client,
-                               u8 rate)
+static int hmc5843_set_samp_freq(struct hmc5843_data *data, u8 rate)
 {
-       struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       u8 reg_val;
+       int ret;
 
-       if (rate >= HMC5843_RATE_NOT_USED) {
-               dev_err(&client->dev,
-                       "data output rate is not supported\n");
-               return -EINVAL;
-       }
+       mutex_lock(&data->lock);
+       ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_A,
+               data->meas_conf | (rate << HMC5843_RATE_OFFSET));
+       if (ret >= 0)
+               data->rate = rate;
+       mutex_unlock(&data->lock);
 
-       reg_val = data->meas_conf | (rate << HMC5843_RATE_OFFSET);
-       return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
+       return ret;
 }
 
-static int hmc5843_check_sampling_frequency(struct hmc5843_data *data,
-                                               const char *buf)
+static int hmc5843_get_samp_freq_index(struct hmc5843_data *data,
+                                  int val, int val2)
 {
-       const char * const *samp_freq = data->variant->regval_to_sample_freq;
        int i;
 
-       for (i = 0; i < HMC5843_RATE_NOT_USED; i++) {
-               if (sysfs_streq(buf, samp_freq[i]))
+       for (i = 0; i < HMC5843_RATES; i++)
+               if (val == data->variant->regval_to_samp_freq[i][0] &&
+                       val2 == data->variant->regval_to_samp_freq[i][1])
                        return i;
-       }
 
        return -EINVAL;
 }
 
-static ssize_t hmc5843_set_sampling_frequency(struct device *dev,
-                                       struct device_attribute *attr,
-                                       const char *buf, size_t count)
+static int hmc5843_set_range_gain(struct hmc5843_data *data, u8 range)
 {
-
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       int rate;
-
-       rate = hmc5843_check_sampling_frequency(data, buf);
-       if (rate < 0) {
-               dev_err(&client->dev,
-                       "sampling frequency is not supported\n");
-               return rate;
-       }
+       int ret;
 
        mutex_lock(&data->lock);
-       dev_dbg(dev, "set rate to %d\n", rate);
-       if (hmc5843_set_rate(client, rate)) {
-               count = -EINVAL;
-               goto exit;
-       }
-       data->rate = rate;
-
-exit:
+       ret = i2c_smbus_write_byte_data(data->client, HMC5843_CONFIG_REG_B,
+               range << HMC5843_RANGE_GAIN_OFFSET);
+       if (ret >= 0)
+               data->range = range;
        mutex_unlock(&data->lock);
-       return count;
+
+       return ret;
 }
 
-static ssize_t hmc5843_show_sampling_frequency(struct device *dev,
-                       struct device_attribute *attr, char *buf)
+static ssize_t hmc5843_show_scale_avail(struct device *dev,
+                               struct device_attribute *attr, char *buf)
 {
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       s32 rate;
+       struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev));
 
-       rate = i2c_smbus_read_byte_data(client, this_attr->address);
-       if (rate < 0)
-               return rate;
-       rate = (rate & HMC5843_RATE_BITMASK) >> HMC5843_RATE_OFFSET;
-       return sprintf(buf, "%s\n", data->variant->regval_to_sample_freq[rate]);
-}
+       size_t len = 0;
+       int i;
 
-static IIO_DEVICE_ATTR(sampling_frequency,
-                       S_IWUSR | S_IRUGO,
-                       hmc5843_show_sampling_frequency,
-                       hmc5843_set_sampling_frequency,
-                       HMC5843_CONFIG_REG_A);
+       for (i = 0; i < HMC5843_RANGE_GAINS; i++)
+               len += scnprintf(buf + len, PAGE_SIZE - len,
+                       "0.%09d ", data->variant->regval_to_nanoscale[i]);
 
-static ssize_t hmc5843_show_range_gain(struct device *dev,
-                               struct device_attribute *attr,
-                               char *buf)
-{
-       u8 range;
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct hmc5843_data *data = iio_priv(indio_dev);
+       /* replace trailing space by newline */
+       buf[len - 1] = '\n';
 
-       range = data->range;
-       return sprintf(buf, "%d\n", data->variant->regval_to_input_field_mga[range]);
+       return len;
 }
 
-static ssize_t hmc5843_set_range_gain(struct device *dev,
-                       struct device_attribute *attr,
-                       const char *buf,
-                       size_t count)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
-       struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-       unsigned long range = 0;
-       int error;
+static IIO_DEVICE_ATTR(scale_available, S_IRUGO,
+       hmc5843_show_scale_avail, NULL, 0);
 
-       mutex_lock(&data->lock);
-       error = kstrtoul(buf, 10, &range);
-       if (error) {
-               count = error;
-               goto exit;
-       }
-       dev_dbg(dev, "set range to %lu\n", range);
+static int hmc5843_get_scale_index(struct hmc5843_data *data, int val, int val2)
+{
+       int i;
 
-       if (range > HMC5843_RANGE_GAIN_MAX) {
-               count = -EINVAL;
-               goto exit;
-       }
+       if (val != 0)
+               return -EINVAL;
 
-       data->range = range;
-       range = range << HMC5843_RANGE_GAIN_OFFSET;
-       if (i2c_smbus_write_byte_data(client, this_attr->address, range))
-               count = -EINVAL;
+       for (i = 0; i < HMC5843_RANGE_GAINS; i++)
+               if (val2 == data->variant->regval_to_nanoscale[i])
+                       return i;
 
-exit:
-       mutex_unlock(&data->lock);
-       return count;
+       return -EINVAL;
 }
 
-static IIO_DEVICE_ATTR(in_magn_range,
-                       S_IWUSR | S_IRUGO,
-                       hmc5843_show_range_gain,
-                       hmc5843_set_range_gain,
-                       HMC5843_CONFIG_REG_B);
-
 static int hmc5843_read_raw(struct iio_dev *indio_dev,
                            struct iio_chan_spec const *chan,
-                           int *val, int *val2,
-                           long mask)
+                           int *val, int *val2, long mask)
 {
        struct hmc5843_data *data = iio_priv(indio_dev);
 
        switch (mask) {
        case IIO_CHAN_INFO_RAW:
-               return hmc5843_read_measurement(indio_dev,
-                                               chan->address,
-                                               val);
+               return hmc5843_read_measurement(data, chan->scan_index, val);
        case IIO_CHAN_INFO_SCALE:
                *val = 0;
                *val2 = data->variant->regval_to_nanoscale[data->range];
                return IIO_VAL_INT_PLUS_NANO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *val = data->variant->regval_to_samp_freq[data->rate][0];
+               *val2 = data->variant->regval_to_samp_freq[data->rate][1];
+               return IIO_VAL_INT_PLUS_MICRO;
        }
        return -EINVAL;
 }
 
-#define HMC5843_CHANNEL(axis, addr)                                    \
+static int hmc5843_write_raw(struct iio_dev *indio_dev,
+                            struct iio_chan_spec const *chan,
+                            int val, int val2, long mask)
+{
+       struct hmc5843_data *data = iio_priv(indio_dev);
+       int rate, range;
+
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               rate = hmc5843_get_samp_freq_index(data, val, val2);
+               if (rate < 0)
+                       return -EINVAL;
+
+               return hmc5843_set_samp_freq(data, rate);
+       case IIO_CHAN_INFO_SCALE:
+               range = hmc5843_get_scale_index(data, val, val2);
+               if (range < 0)
+                       return -EINVAL;
+
+               return hmc5843_set_range_gain(data, range);
+       default:
+               return -EINVAL;
+       }
+}
+
+static int hmc5843_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_NANO;
+       default:
+               return -EINVAL;
+       }
+}
+
+static irqreturn_t hmc5843_trigger_handler(int irq, void *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct hmc5843_data *data = iio_priv(indio_dev);
+       int ret;
+
+       mutex_lock(&data->lock);
+       ret = hmc5843_wait_measurement(data);
+       if (ret < 0) {
+               mutex_unlock(&data->lock);
+               goto done;
+       }
+
+       ret = i2c_smbus_read_i2c_block_data(data->client,
+               HMC5843_DATA_OUT_MSB_REGS, 3 * sizeof(__be16),
+                       (u8 *) data->buffer);
+       mutex_unlock(&data->lock);
+       if (ret < 0)
+               goto done;
+
+       iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
+               iio_get_time_ns());
+
+done:
+       iio_trigger_notify_done(indio_dev->trig);
+
+       return IRQ_HANDLED;
+}
+
+#define HMC5843_CHANNEL(axis, idx)                                     \
        {                                                               \
                .type = IIO_MAGN,                                       \
                .modified = 1,                                          \
                .channel2 = IIO_MOD_##axis,                             \
                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
-               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),   \
-               .address = addr                                         \
+               .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
+                       BIT(IIO_CHAN_INFO_SAMP_FREQ),                   \
+               .scan_index = idx,                                      \
+               .scan_type = IIO_ST('s', 16, 16, IIO_BE),               \
        }
 
 static const struct iio_chan_spec hmc5843_channels[] = {
-       HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
-       HMC5843_CHANNEL(Y, HMC5843_DATA_OUT_Y_MSB_REG),
-       HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG),
+       HMC5843_CHANNEL(X, 0),
+       HMC5843_CHANNEL(Y, 1),
+       HMC5843_CHANNEL(Z, 2),
+       IIO_CHAN_SOFT_TIMESTAMP(3),
 };
 
+/* Beware: Y and Z are exchanged on HMC5883 */
 static const struct iio_chan_spec hmc5883_channels[] = {
-       HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG),
-       HMC5843_CHANNEL(Y, HMC5883_DATA_OUT_Y_MSB_REG),
-       HMC5843_CHANNEL(Z, HMC5883_DATA_OUT_Z_MSB_REG),
+       HMC5843_CHANNEL(X, 0),
+       HMC5843_CHANNEL(Z, 1),
+       HMC5843_CHANNEL(Y, 2),
+       IIO_CHAN_SOFT_TIMESTAMP(3),
 };
 
 static struct attribute *hmc5843_attributes[] = {
        &iio_dev_attr_meas_conf.dev_attr.attr,
-       &iio_dev_attr_operating_mode.dev_attr.attr,
-       &iio_dev_attr_sampling_frequency.dev_attr.attr,
-       &iio_dev_attr_in_magn_range.dev_attr.attr,
+       &iio_dev_attr_scale_available.dev_attr.attr,
        &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
        NULL
 };
@@ -590,89 +483,101 @@ static const struct attribute_group hmc5843_group = {
 static const struct hmc5843_chip_info hmc5843_chip_info_tbl[] = {
        [HMC5843_ID] = {
                .channels = hmc5843_channels,
-               .regval_to_sample_freq = hmc5843_regval_to_sample_freq,
-               .regval_to_input_field_mga =
-                       hmc5843_regval_to_input_field_mga,
+               .regval_to_samp_freq = hmc5843_regval_to_samp_freq,
                .regval_to_nanoscale = hmc5843_regval_to_nanoscale,
        },
        [HMC5883_ID] = {
                .channels = hmc5883_channels,
-               .regval_to_sample_freq = hmc5883_regval_to_sample_freq,
-               .regval_to_input_field_mga =
-                       hmc5883_regval_to_input_field_mga,
+               .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
                .regval_to_nanoscale = hmc5883_regval_to_nanoscale,
        },
        [HMC5883L_ID] = {
                .channels = hmc5883_channels,
-               .regval_to_sample_freq = hmc5883_regval_to_sample_freq,
-               .regval_to_input_field_mga =
-                       hmc5883l_regval_to_input_field_mga,
+               .regval_to_samp_freq = hmc5883_regval_to_samp_freq,
                .regval_to_nanoscale = hmc5883l_regval_to_nanoscale,
        },
 };
 
-/* Called when we have found a new HMC58X3 */
-static void hmc5843_init_client(struct i2c_client *client,
-                               const struct i2c_device_id *id)
+static int hmc5843_init(struct hmc5843_data *data)
 {
-       struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct hmc5843_data *data = iio_priv(indio_dev);
-
-       data->variant = &hmc5843_chip_info_tbl[id->driver_data];
-       indio_dev->channels = data->variant->channels;
-       indio_dev->num_channels = 3;
-       hmc5843_set_meas_conf(client, data->meas_conf);
-       hmc5843_set_rate(client, data->rate);
-       hmc5843_configure(client, data->operating_mode);
-       i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
-       mutex_init(&data->lock);
+       int ret;
+       u8 id[3];
+
+       ret = i2c_smbus_read_i2c_block_data(data->client, HMC5843_ID_REG,
+               sizeof(id), id);
+       if (ret < 0)
+               return ret;
+       if (id[0] != 'H' || id[1] != '4' || id[2] != '3') {
+               dev_err(&data->client->dev, "no HMC5843/5883/5883L sensor\n");
+               return -ENODEV;
+       }
 
-       pr_info("%s initialized\n", id->name);
+       ret = hmc5843_set_meas_conf(data, HMC5843_MEAS_CONF_NORMAL);
+       if (ret < 0)
+               return ret;
+       ret = hmc5843_set_samp_freq(data, HMC5843_RATE_DEFAULT);
+       if (ret < 0)
+               return ret;
+       ret = hmc5843_set_range_gain(data, HMC5843_RANGE_GAIN_DEFAULT);
+       if (ret < 0)
+               return ret;
+       return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
 }
 
 static const struct iio_info hmc5843_info = {
        .attrs = &hmc5843_group,
        .read_raw = &hmc5843_read_raw,
+       .write_raw = &hmc5843_write_raw,
+       .write_raw_get_fmt = &hmc5843_write_raw_get_fmt,
        .driver_module = THIS_MODULE,
 };
 
+static const unsigned long hmc5843_scan_masks[] = {0x7, 0};
+
 static int hmc5843_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
        struct hmc5843_data *data;
        struct iio_dev *indio_dev;
-       int err = 0;
+       int ret;
 
-       indio_dev = iio_device_alloc(sizeof(*data));
-       if (indio_dev == NULL) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+       if (indio_dev == NULL)
+               return -ENOMEM;
 
        /* default settings at probe */
        data = iio_priv(indio_dev);
-       data->meas_conf = HMC5843_MEAS_CONF_NORMAL;
-       data->range = HMC5843_RANGE_GAIN_DEFAULT;
-       data->operating_mode = HMC5843_MODE_CONVERSION_CONTINUOUS;
+       data->client = client;
+       data->variant = &hmc5843_chip_info_tbl[id->driver_data];
+       mutex_init(&data->lock);
 
        i2c_set_clientdata(client, indio_dev);
-       hmc5843_init_client(client, id);
-
        indio_dev->info = &hmc5843_info;
        indio_dev->name = id->name;
        indio_dev->dev.parent = &client->dev;
        indio_dev->modes = INDIO_DIRECT_MODE;
+       indio_dev->channels = data->variant->channels;
+       indio_dev->num_channels = 4;
+       indio_dev->available_scan_masks = hmc5843_scan_masks;
+
+       ret = hmc5843_init(data);
+       if (ret < 0)
+               return ret;
+
+       ret = iio_triggered_buffer_setup(indio_dev, NULL,
+               hmc5843_trigger_handler, NULL);
+       if (ret < 0)
+               return ret;
 
-       err = iio_device_register(indio_dev);
-       if (err)
-               goto exit_free2;
+       ret = iio_device_register(indio_dev);
+       if (ret < 0)
+               goto buffer_cleanup;
 
        return 0;
 
-exit_free2:
-       iio_device_free(indio_dev);
-exit:
-       return err;
+buffer_cleanup:
+       iio_triggered_buffer_cleanup(indio_dev);
+       return ret;
 }
 
 static int hmc5843_remove(struct i2c_client *client)
@@ -680,9 +585,10 @@ static int hmc5843_remove(struct i2c_client *client)
        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 
        iio_device_unregister(indio_dev);
-        /*  sleep mode to save power */
-       hmc5843_configure(client, HMC5843_MODE_SLEEP);
-       iio_device_free(indio_dev);
+       iio_triggered_buffer_cleanup(indio_dev);
+
+       /*  sleep mode to save power */
+       hmc5843_set_mode(iio_priv(indio_dev), HMC5843_MODE_SLEEP);
 
        return 0;
 }
@@ -690,19 +596,18 @@ static int hmc5843_remove(struct i2c_client *client)
 #ifdef CONFIG_PM_SLEEP
 static int hmc5843_suspend(struct device *dev)
 {
-       hmc5843_configure(to_i2c_client(dev), HMC5843_MODE_SLEEP);
-       return 0;
+       struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
+
+       return hmc5843_set_mode(data, HMC5843_MODE_SLEEP);
 }
 
 static int hmc5843_resume(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct iio_dev *indio_dev = i2c_get_clientdata(client);
-       struct hmc5843_data *data = iio_priv(indio_dev);
+       struct hmc5843_data *data = iio_priv(i2c_get_clientdata(
+               to_i2c_client(dev)));
 
-       hmc5843_configure(client, data->operating_mode);
-
-       return 0;
+       return hmc5843_set_mode(data, HMC5843_MODE_CONVERSION_CONTINUOUS);
 }
 
 static SIMPLE_DEV_PM_OPS(hmc5843_pm_ops, hmc5843_suspend, hmc5843_resume);
@@ -730,6 +635,6 @@ static struct i2c_driver hmc5843_driver = {
 };
 module_i2c_driver(hmc5843_driver);
 
-MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
+MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");
 MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
 MODULE_LICENSE("GPL");
index abfc8bd1794d03e4f89e75b1362b40a22d783f17..00492cad7c57fb9778bc85881bd3fba02e513b3b 100644 (file)
@@ -185,9 +185,9 @@ static ssize_t ade7753_write_8bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u8 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7753_spi_write_reg_8(dev, this_attr->address, val);
@@ -203,9 +203,9 @@ static ssize_t ade7753_write_16bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u16 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7753_spi_write_reg_16(dev, this_attr->address, val);
@@ -398,11 +398,11 @@ static ssize_t ade7753_write_frequency(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ade7753_state *st = iio_priv(indio_dev);
-       unsigned long val;
+       u16 val;
        int ret;
        u16 reg, t;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                return ret;
        if (val == 0)
@@ -496,11 +496,9 @@ static int ade7753_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
 
        /* setup the industrialio driver allocated elements */
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        /* this is only used for removal purposes */
        spi_set_drvdata(spi, indio_dev);
 
@@ -516,19 +514,13 @@ static int ade7753_probe(struct spi_device *spi)
        /* Get the device into a sane initial state */
        ret = ade7753_initial_setup(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        return 0;
-
-error_free_dev:
-       iio_device_free(indio_dev);
-
-error_ret:
-       return ret;
 }
 
 /* fixme, confirm ordering in this function */
@@ -538,7 +530,6 @@ static int ade7753_remove(struct spi_device *spi)
 
        iio_device_unregister(indio_dev);
        ade7753_stop_device(&indio_dev->dev);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 3d1c02cd65384db7a9d6fa8e87eaa0542510e0db..e0aa13ab3657bad3dbd4e1e6424a10fd3ff526ba 100644 (file)
@@ -185,9 +185,9 @@ static ssize_t ade7754_write_8bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u8 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7754_spi_write_reg_8(dev, this_attr->address, val);
@@ -203,9 +203,9 @@ static ssize_t ade7754_write_16bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u16 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7754_spi_write_reg_16(dev, this_attr->address, val);
@@ -418,11 +418,11 @@ static ssize_t ade7754_write_frequency(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ade7754_state *st = iio_priv(indio_dev);
-       unsigned long val;
+       u16 val;
        int ret;
        u8 reg, t;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                return ret;
        if (val == 0)
@@ -519,11 +519,9 @@ static int ade7754_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
 
        /* setup the industrialio driver allocated elements */
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        /* this is only used for removal purposes */
        spi_set_drvdata(spi, indio_dev);
 
@@ -539,18 +537,12 @@ static int ade7754_probe(struct spi_device *spi)
        /* Get the device into a sane initial state */
        ret = ade7754_initial_setup(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        return 0;
-
-error_free_dev:
-       iio_device_free(indio_dev);
-
-error_ret:
-       return ret;
 }
 
 /* fixme, confirm ordering in this function */
@@ -560,7 +552,6 @@ static int ade7754_remove(struct spi_device *spi)
 
        iio_device_unregister(indio_dev);
        ade7754_stop_device(&indio_dev->dev);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 6005d4aab0c346365c7f76ed0047bfb6f2b81cda..cba183e24838e64bd4f69d5e102981118ac9e262 100644 (file)
@@ -269,9 +269,9 @@ static ssize_t ade7758_write_8bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u8 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7758_spi_write_reg_8(dev, this_attr->address, val);
@@ -287,9 +287,9 @@ static ssize_t ade7758_write_16bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u16 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7758_spi_write_reg_16(dev, this_attr->address, val);
@@ -502,11 +502,11 @@ static ssize_t ade7758_write_frequency(struct device *dev,
                size_t len)
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       unsigned long val;
+       u16 val;
        int ret;
        u8 reg, t;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                return ret;
 
@@ -849,12 +849,11 @@ static int ade7758_probe(struct spi_device *spi)
 {
        int ret;
        struct ade7758_state *st;
-       struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
+       struct iio_dev *indio_dev;
 
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
 
        st = iio_priv(indio_dev);
        /* this is only used for removal purposes */
@@ -862,10 +861,8 @@ static int ade7758_probe(struct spi_device *spi)
 
        /* Allocate the comms buffers */
        st->rx = kcalloc(ADE7758_MAX_RX, sizeof(*st->rx), GFP_KERNEL);
-       if (st->rx == NULL) {
-               ret = -ENOMEM;
-               goto error_free_dev;
-       }
+       if (!st->rx)
+               return -ENOMEM;
        st->tx = kcalloc(ADE7758_MAX_TX, sizeof(*st->tx), GFP_KERNEL);
        if (st->tx == NULL) {
                ret = -ENOMEM;
@@ -920,9 +917,6 @@ error_free_tx:
        kfree(st->tx);
 error_free_rx:
        kfree(st->rx);
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
        return ret;
 }
 
@@ -939,8 +933,6 @@ static int ade7758_remove(struct spi_device *spi)
        kfree(st->tx);
        kfree(st->rx);
 
-       iio_device_free(indio_dev);
-
        return 0;
 }
 
index 7d5db71755788372638035b49917e5470cf4bc68..c0accf8cce93f1fdbd3ad3a3d4213220ddb87b17 100644 (file)
@@ -69,11 +69,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
                if (ade7758_spi_read_burst(indio_dev) >= 0)
                        *dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
 
-       /* Guaranteed to be aligned with 8 byte boundary */
-       if (indio_dev->scan_timestamp)
-               dat64[1] = pf->timestamp;
-
-       iio_push_to_buffers(indio_dev, (u8 *)dat64);
+       iio_push_to_buffers_with_timestamp(indio_dev, dat64, pf->timestamp);
 
        iio_trigger_notify_done(indio_dev->trig);
 
@@ -91,15 +87,10 @@ static int ade7758_ring_preenable(struct iio_dev *indio_dev)
 {
        struct ade7758_state *st = iio_priv(indio_dev);
        unsigned channel;
-       int ret;
 
        if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
                return -EINVAL;
 
-       ret = iio_sw_buffer_preenable(indio_dev);
-       if (ret < 0)
-               return ret;
-
        channel = find_first_bit(indio_dev->active_scan_mask,
                                 indio_dev->masklength);
 
@@ -125,14 +116,17 @@ void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 int ade7758_configure_ring(struct iio_dev *indio_dev)
 {
        struct ade7758_state *st = iio_priv(indio_dev);
+       struct iio_buffer *buffer;
        int ret = 0;
 
-       indio_dev->buffer = iio_kfifo_allocate(indio_dev);
-       if (!indio_dev->buffer) {
+       buffer = iio_kfifo_allocate(indio_dev);
+       if (!buffer) {
                ret = -ENOMEM;
                return ret;
        }
 
+       iio_device_attach_buffer(indio_dev, buffer);
+
        indio_dev->setup_ops = &ade7758_ring_setup_ops;
 
        indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
index 7467e51fd42497c4885a953b34e7e644358a5945..ea0c9debf8bf90604669ce9ad982a7fa6eac0dd6 100644 (file)
@@ -184,9 +184,9 @@ static ssize_t ade7759_write_8bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u8 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7759_spi_write_reg_8(dev, this_attr->address, val);
@@ -202,9 +202,9 @@ static ssize_t ade7759_write_16bit(struct device *dev,
 {
        struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
        int ret;
-       long val;
+       u16 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = ade7759_spi_write_reg_16(dev, this_attr->address, val);
@@ -359,11 +359,11 @@ static ssize_t ade7759_write_frequency(struct device *dev,
 {
        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
        struct ade7759_state *st = iio_priv(indio_dev);
-       unsigned long val;
+       u16 val;
        int ret;
        u16 reg, t;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                return ret;
        if (val == 0)
@@ -443,11 +443,9 @@ static int ade7759_probe(struct spi_device *spi)
        struct iio_dev *indio_dev;
 
        /* setup the industrialio driver allocated elements */
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        /* this is only used for removal purposes */
        spi_set_drvdata(spi, indio_dev);
 
@@ -462,18 +460,13 @@ static int ade7759_probe(struct spi_device *spi)
        /* Get the device into a sane initial state */
        ret = ade7759_initial_setup(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        return 0;
-
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
-       return ret;
 }
 
 /* fixme, confirm ordering in this function */
@@ -483,7 +476,6 @@ static int ade7759_remove(struct spi_device *spi)
 
        iio_device_unregister(indio_dev);
        ade7759_stop_device(&indio_dev->dev);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index db9ef6c86c1edad8df8ef5f94e725ff8021a5c25..5b33c7f1aa9108652fb4d6f7d8ceb81048646113 100644 (file)
@@ -208,7 +208,7 @@ static int ade7854_i2c_probe(struct i2c_client *client,
        struct ade7854_state *st;
        struct iio_dev *indio_dev;
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
        st = iio_priv(indio_dev);
@@ -225,8 +225,6 @@ static int ade7854_i2c_probe(struct i2c_client *client,
        st->irq = client->irq;
 
        ret = ade7854_probe(indio_dev, &client->dev);
-       if (ret)
-               iio_device_free(indio_dev);
 
        return ret;
 }
index 4c6d2041260bed259f7cba174c64ceb9a9c1a3f8..94f73bbbc0fd28ec65153b401ef5a401d32d24d2 100644 (file)
@@ -278,7 +278,7 @@ static int ade7854_spi_probe(struct spi_device *spi)
        struct ade7854_state *st;
        struct iio_dev *indio_dev;
 
-       indio_dev = iio_device_alloc(sizeof(*st));
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
        if (indio_dev == NULL)
                return -ENOMEM;
        st = iio_priv(indio_dev);
@@ -296,8 +296,6 @@ static int ade7854_spi_probe(struct spi_device *spi)
 
 
        ret = ade7854_probe(indio_dev, &spi->dev);
-       if (ret)
-               iio_device_free(indio_dev);
 
        return ret;
 }
index e8379c0f1173ffc454067788d16cd39ee8bc48fb..d620bbd603a30db2264bb5f8499c142eb19a3d8c 100644 (file)
@@ -100,9 +100,9 @@ static ssize_t ade7854_write_8bit(struct device *dev,
        struct ade7854_state *st = iio_priv(indio_dev);
 
        int ret;
-       long val;
+       u8 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou8(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = st->write_reg_8(dev, this_attr->address, val);
@@ -121,9 +121,9 @@ static ssize_t ade7854_write_16bit(struct device *dev,
        struct ade7854_state *st = iio_priv(indio_dev);
 
        int ret;
-       long val;
+       u16 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou16(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = st->write_reg_16(dev, this_attr->address, val);
@@ -142,9 +142,9 @@ static ssize_t ade7854_write_24bit(struct device *dev,
        struct ade7854_state *st = iio_priv(indio_dev);
 
        int ret;
-       long val;
+       u32 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou32(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = st->write_reg_24(dev, this_attr->address, val);
@@ -163,9 +163,9 @@ static ssize_t ade7854_write_32bit(struct device *dev,
        struct ade7854_state *st = iio_priv(indio_dev);
 
        int ret;
-       long val;
+       u32 val;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = kstrtou32(buf, 10, &val);
        if (ret)
                goto error_ret;
        ret = st->write_reg_32(dev, this_attr->address, val);
@@ -550,7 +550,7 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        /* Get the device into a sane initial state */
        ret = ade7854_initial_setup(indio_dev);
@@ -561,9 +561,6 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
 
 error_unreg_dev:
        iio_device_unregister(indio_dev);
-error_free_dev:
-       iio_device_free(indio_dev);
-
        return ret;
 }
 EXPORT_SYMBOL(ade7854_probe);
@@ -571,7 +568,6 @@ EXPORT_SYMBOL(ade7854_probe);
 int ade7854_remove(struct iio_dev *indio_dev)
 {
        iio_device_unregister(indio_dev);
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 71221161aa6b983f37c438755c1d3a5085d34bf5..62d30179301fa52e0d6b9322d553371641b952e2 100644 (file)
@@ -107,16 +107,16 @@ static int ad2s1200_probe(struct spi_device *spi)
        unsigned short *pins = spi->dev.platform_data;
 
        for (pn = 0; pn < AD2S1200_PN; pn++)
-               if (gpio_request_one(pins[pn], GPIOF_DIR_OUT, DRV_NAME)) {
-                       pr_err("%s: request gpio pin %d failed\n",
-                                               DRV_NAME, pins[pn]);
-                       goto error_ret;
+               ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT,
+                                           DRV_NAME);
+               if (ret) {
+                       dev_err(&spi->dev, "request gpio pin %d failed\n",
+                                                       pins[pn]);
+                       return ret;
                }
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        spi_set_drvdata(spi, indio_dev);
        st = iio_priv(indio_dev);
        mutex_init(&st->lock);
@@ -133,26 +133,18 @@ static int ad2s1200_probe(struct spi_device *spi)
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        spi->max_speed_hz = AD2S1200_HZ;
        spi->mode = SPI_MODE_3;
        spi_setup(spi);
 
        return 0;
-
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
-       for (--pn; pn >= 0; pn--)
-               gpio_free(pins[pn]);
-       return ret;
 }
 
 static int ad2s1200_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index dcdadbbcf7e864978fbd119721f1cf058ba69234..6966d5f766481befae4cb5d250434842acc06bc1 100644 (file)
@@ -206,10 +206,10 @@ static ssize_t ad2s1210_store_fclkin(struct device *dev,
                                     size_t len)
 {
        struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-       unsigned long fclkin;
+       unsigned int fclkin;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &fclkin);
+       ret = kstrtouint(buf, 10, &fclkin);
        if (ret)
                return ret;
        if (fclkin < AD2S1210_MIN_CLKIN || fclkin > AD2S1210_MAX_CLKIN) {
@@ -243,10 +243,10 @@ static ssize_t ad2s1210_store_fexcit(struct device *dev,
                                     const char *buf, size_t len)
 {
        struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-       unsigned long fexcit;
+       unsigned int fexcit;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &fexcit);
+       ret = kstrtouint(buf, 10, &fexcit);
        if (ret < 0)
                return ret;
        if (fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT) {
@@ -282,11 +282,11 @@ static ssize_t ad2s1210_store_control(struct device *dev,
                        const char *buf, size_t len)
 {
        struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-       unsigned long udata;
+       unsigned char udata;
        unsigned char data;
        int ret;
 
-       ret = strict_strtoul(buf, 16, &udata);
+       ret = kstrtou8(buf, 16, &udata);
        if (ret)
                return -EINVAL;
 
@@ -337,10 +337,10 @@ static ssize_t ad2s1210_store_resolution(struct device *dev,
 {
        struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
        unsigned char data;
-       unsigned long udata;
+       unsigned char udata;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &udata);
+       ret = kstrtou8(buf, 10, &udata);
        if (ret || udata < 10 || udata > 16) {
                pr_err("ad2s1210: resolution out of range\n");
                return -EINVAL;
@@ -438,11 +438,11 @@ static ssize_t ad2s1210_store_reg(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t len)
 {
        struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
-       unsigned long data;
+       unsigned char data;
        int ret;
        struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
 
-       ret = strict_strtoul(buf, 10, &data);
+       ret = kstrtou8(buf, 10, &data);
        if (ret)
                return -EINVAL;
        mutex_lock(&st->lock);
@@ -669,16 +669,14 @@ static int ad2s1210_probe(struct spi_device *spi)
        if (spi->dev.platform_data == NULL)
                return -EINVAL;
 
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        st = iio_priv(indio_dev);
        st->pdata = spi->dev.platform_data;
        ret = ad2s1210_setup_gpios(st);
        if (ret < 0)
-               goto error_free_dev;
+               return ret;
 
        spi_set_drvdata(spi, indio_dev);
 
@@ -709,9 +707,6 @@ static int ad2s1210_probe(struct spi_device *spi)
 
 error_free_gpios:
        ad2s1210_free_gpios(st);
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
        return ret;
 }
 
@@ -721,7 +716,6 @@ static int ad2s1210_remove(struct spi_device *spi)
 
        iio_device_unregister(indio_dev);
        ad2s1210_free_gpios(iio_priv(indio_dev));
-       iio_device_free(indio_dev);
 
        return 0;
 }
index 40b825286d4af65dfe9228baa76c0af392096fa9..e24c5890652f8d1c1b0280875f25cde6fb0050a5 100644 (file)
@@ -64,11 +64,9 @@ static int ad2s90_probe(struct spi_device *spi)
        struct ad2s90_state *st;
        int ret = 0;
 
-       indio_dev = iio_device_alloc(sizeof(*st));
-       if (indio_dev == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+       if (!indio_dev)
+               return -ENOMEM;
        st = iio_priv(indio_dev);
        spi_set_drvdata(spi, indio_dev);
 
@@ -83,7 +81,7 @@ static int ad2s90_probe(struct spi_device *spi)
 
        ret = iio_device_register(indio_dev);
        if (ret)
-               goto error_free_dev;
+               return ret;
 
        /* need 600ns between CS and the first falling edge of SCLK */
        spi->max_speed_hz = 830000;
@@ -91,17 +89,11 @@ static int ad2s90_probe(struct spi_device *spi)
        spi_setup(spi);
 
        return 0;
-
-error_free_dev:
-       iio_device_free(indio_dev);
-error_ret:
-       return ret;
 }
 
 static int ad2s90_remove(struct spi_device *spi)
 {
        iio_device_unregister(spi_get_drvdata(spi));
-       iio_device_free(spi_get_drvdata(spi));
 
        return 0;
 }
index 38a158b77b1d24f3d55ac12c08ae13b0792b8d20..26e1ca0b7800223b88f3102d562d0c7c084087bb 100644 (file)
@@ -83,32 +83,28 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
 {
        struct iio_trigger *trig = to_iio_trigger(dev);
        struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig);
-       unsigned long val;
+       unsigned int val;
        bool enabled;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &val);
+       ret = kstrtouint(buf, 10, &val);
        if (ret)
-               goto error_ret;
+               return ret;
 
-       if (val > 100000) {
-               ret = -EINVAL;
-               goto error_ret;
-       }
+       if (val > 100000)
+               return -EINVAL;
 
        enabled = get_enabled_gptimers() & st->t->bit;
 
        if (enabled)
                disable_gptimers(st->t->bit);
 
-       if (!val)
-               goto error_ret;
+       if (val == 0)
+               return count;
 
        val = get_sclk() / val;
-       if (val <= 4 || val <= st->duty) {
-               ret = -EINVAL;
-               goto error_ret;
-       }
+       if (val <= 4 || val <= st->duty)
+               return -EINVAL;
 
        set_gptimer_period(st->t->id, val);
        set_gptimer_pwidth(st->t->id, val - st->duty);
@@ -116,8 +112,7 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
        if (enabled)
                enable_gptimers(st->t->bit);
 
-error_ret:
-       return ret ? ret : count;
+       return count;
 }
 
 static ssize_t iio_bfin_tmr_frequency_show(struct device *dev,
index 79695974b1d43dde0a46e1dbf60e00254edd0807..48a6afa8408805ff3a8f2ab25689ebccc3e419cf 100644 (file)
@@ -53,10 +53,10 @@ static ssize_t iio_trig_periodic_write_freq(struct device *dev,
 {
        struct iio_trigger *trig = to_iio_trigger(dev);
        struct iio_prtc_trigger_info *trig_info = iio_trigger_get_drvdata(trig);
-       unsigned long val;
+       int val;
        int ret;
 
-       ret = strict_strtoul(buf, 10, &val);
+       ret = kstrtoint(buf, 10, &val);
        if (ret)
                goto error_ret;
 
index bfaf69378ac208b33f8ec3e956be0d2136b802dc..2c3a9e178fb5e65a073dc777b1c7dd86c7a9f34f 100644 (file)
@@ -8,4 +8,4 @@ obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o
 obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
 obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o
 obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/
-obj-$(CONFIG_DRM_IMX_IPUV3)    += ipuv3-crtc.o
+obj-$(CONFIG_DRM_IMX_IPUV3)    += ipuv3-crtc.o ipuv3-plane.o
index 9cfa2a7efdc06818a91fa81e11f8ee34530fcddf..6a9da94c957341a1a09312414bb687848cb688d2 100644 (file)
@@ -9,7 +9,6 @@ TODO:
 
 Missing features (not necessarily for moving out of staging):
 
-- Add KMS plane support for CRTC driver
 - Add i.MX6 HDMI support
 - Add support for IC (Image converter)
 - Add support for CSI (CMOS Sensor interface)
index ad135d3c3281f40f3d45b4148c0538cf05a7cc37..2828311bf039103afddfb0285b84cfbf8d464e53 100644 (file)
@@ -68,6 +68,11 @@ struct imx_drm_connector {
        struct module                           *owner;
 };
 
+int imx_drm_crtc_id(struct imx_drm_crtc *crtc)
+{
+       return crtc->pipe;
+}
+
 static void imx_drm_driver_lastclose(struct drm_device *drm)
 {
        struct imx_drm_device *imxdrm = drm->dev_private;
@@ -110,18 +115,12 @@ int imx_drm_crtc_panel_format_pins(struct drm_crtc *crtc, u32 encoder_type,
        struct imx_drm_crtc *imx_crtc;
        struct imx_drm_crtc_helper_funcs *helper;
 
-       mutex_lock(&imxdrm->mutex);
-
        list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list)
                if (imx_crtc->crtc == crtc)
                        goto found;
 
-       mutex_unlock(&imxdrm->mutex);
-
        return -EINVAL;
 found:
-       mutex_unlock(&imxdrm->mutex);
-
        helper = &imx_crtc->imx_drm_helper_funcs;
        if (helper->set_interface_pix_fmt)
                return helper->set_interface_pix_fmt(crtc,
@@ -191,6 +190,18 @@ static void imx_drm_disable_vblank(struct drm_device *drm, int crtc)
        imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc);
 }
 
+static void imx_drm_driver_preclose(struct drm_device *drm,
+               struct drm_file *file)
+{
+       int i;
+
+       if (!file->is_master)
+               return;
+
+       for (i = 0; i < 4; i++)
+               imx_drm_disable_vblank(drm , i);
+}
+
 static const struct file_operations imx_drm_driver_fops = {
        .owner = THIS_MODULE,
        .open = drm_open,
@@ -647,20 +658,14 @@ int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder,
        struct imx_drm_crtc *imx_crtc;
        int i = 0;
 
-       mutex_lock(&imxdrm->mutex);
-
        list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) {
                if (imx_crtc->crtc == crtc)
                        goto found;
                i++;
        }
 
-       mutex_unlock(&imxdrm->mutex);
-
        return -EINVAL;
 found:
-       mutex_unlock(&imxdrm->mutex);
-
        return i;
 }
 EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id);
@@ -774,16 +779,26 @@ static const struct drm_ioctl_desc imx_drm_ioctls[] = {
 };
 
 static struct drm_driver imx_drm_driver = {
-       .driver_features        = DRIVER_MODESET | DRIVER_GEM,
+       .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
        .load                   = imx_drm_driver_load,
        .unload                 = imx_drm_driver_unload,
        .lastclose              = imx_drm_driver_lastclose,
+       .preclose               = imx_drm_driver_preclose,
        .gem_free_object        = drm_gem_cma_free_object,
        .gem_vm_ops             = &drm_gem_cma_vm_ops,
        .dumb_create            = drm_gem_cma_dumb_create,
        .dumb_map_offset        = drm_gem_cma_dumb_map_offset,
        .dumb_destroy           = drm_gem_dumb_destroy,
 
+       .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
+       .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
+       .gem_prime_import       = drm_gem_prime_import,
+       .gem_prime_export       = drm_gem_prime_export,
+       .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
+       .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+       .gem_prime_vmap         = drm_gem_cma_prime_vmap,
+       .gem_prime_vunmap       = drm_gem_cma_prime_vunmap,
+       .gem_prime_mmap         = drm_gem_cma_prime_mmap,
        .get_vblank_counter     = drm_vblank_count,
        .enable_vblank          = imx_drm_enable_vblank,
        .disable_vblank         = imx_drm_disable_vblank,
index f2aac91ddf5d51e45f739c041e57b53c5eb868e5..ae90c9c15312c2ca57fb1884b622a8bf0469cf0e 100644 (file)
@@ -14,6 +14,8 @@ struct drm_fbdev_cma;
 struct drm_framebuffer;
 struct platform_device;
 
+int imx_drm_crtc_id(struct imx_drm_crtc *crtc);
+
 struct imx_drm_crtc_helper_funcs {
        int (*enable_vblank)(struct drm_crtc *crtc);
        void (*disable_vblank)(struct drm_crtc *crtc);
index af733ea485656877e86cc9ae760846fa81deb3d0..926f49339b2619ee136e16f5474369b971aa9dc5 100644 (file)
@@ -421,7 +421,7 @@ static const char *imx_ldb_bit_mappings[] = {
        [LVDS_BIT_MAP_JEIDA] = "jeida",
 };
 
-const int of_get_data_mapping(struct device_node *np)
+static const int of_get_data_mapping(struct device_node *np)
 {
        const char *bm;
        int ret, i;
@@ -466,8 +466,7 @@ static int imx_ldb_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        const struct of_device_id *of_id =
-                       of_match_device(of_match_ptr(imx_ldb_dt_ids),
-                                       &pdev->dev);
+                       of_match_device(imx_ldb_dt_ids, &pdev->dev);
        struct device_node *child;
        const u8 *edidp;
        struct imx_ldb *imx_ldb;
index 33d6525cf9960c5b4a36b2114a6f9fffc9ca7711..59dd4d560ce036ea6001707d3601153c505a22aa 100644 (file)
@@ -696,7 +696,7 @@ static int imx_tve_probe(struct platform_device *pdev)
        if (val != 0x00100000) {
                dev_err(&pdev->dev, "configuration register default value indicates this is not a TVEv2\n");
                return -ENODEV;
-       };
+       }
 
        /* disable cable detection for VGA mode */
        ret = regmap_write(tve->regmap, TVE_CD_CONT_REG, 0);
index 74c022e2a5324ce2042363890d84f9e530075988..4826b5c0249d1b202cd69b8474d35a2729962c18 100644 (file)
@@ -97,6 +97,7 @@ void ipu_idmac_put(struct ipuv3_channel *);
 
 int ipu_idmac_enable_channel(struct ipuv3_channel *channel);
 int ipu_idmac_disable_channel(struct ipuv3_channel *channel);
+int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms);
 
 void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
                bool doublebuffer);
@@ -283,7 +284,7 @@ int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p,
                int width);
 
 int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *,
-               struct ipu_rgb *rgb);
+               const struct ipu_rgb *rgb);
 
 static inline void ipu_cpmem_interlaced_scan(struct ipu_ch_param *p,
                int stride)
@@ -303,6 +304,7 @@ int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat);
 int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
                struct ipu_image *image);
 
+enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc);
 enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat);
 
 static inline void ipu_cpmem_set_burstsize(struct ipu_ch_param __iomem *p,
index ba464e5d9f125ede776ad56a47f9181442667d11..a0e7fc2f40319fbb78a1cdd483f37ffcd122f2fd 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/irqdomain.h>
 #include <linux/of_device.h>
 
+#include <drm/drm_fourcc.h>
+
 #include "imx-ipu-v3.h"
 #include "ipu-prv.h"
 
@@ -139,7 +141,7 @@ u32 ipu_ch_param_read_field(struct ipu_ch_param __iomem *base, u32 wbs)
 EXPORT_SYMBOL_GPL(ipu_ch_param_read_field);
 
 int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *p,
-               struct ipu_rgb *rgb)
+               const struct ipu_rgb *rgb)
 {
        int bpp = 0, npb = 0, ro, go, bo, to;
 
@@ -282,7 +284,7 @@ void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format,
 }
 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar);
 
-static struct ipu_rgb def_rgb_32 = {
+static const struct ipu_rgb def_rgb_32 = {
        .red    = { .offset = 16, .length = 8, },
        .green  = { .offset =  8, .length = 8, },
        .blue   = { .offset =  0, .length = 8, },
@@ -290,31 +292,31 @@ static struct ipu_rgb def_rgb_32 = {
        .bits_per_pixel = 32,
 };
 
-static struct ipu_rgb def_bgr_32 = {
-       .red    = { .offset = 16, .length = 8, },
+static const struct ipu_rgb def_bgr_32 = {
+       .red    = { .offset =  0, .length = 8, },
        .green  = { .offset =  8, .length = 8, },
-       .blue   = { .offset =  0, .length = 8, },
+       .blue   = { .offset = 16, .length = 8, },
        .transp = { .offset = 24, .length = 8, },
        .bits_per_pixel = 32,
 };
 
-static struct ipu_rgb def_rgb_24 = {
-       .red    = { .offset =  0, .length = 8, },
+static const struct ipu_rgb def_rgb_24 = {
+       .red    = { .offset = 16, .length = 8, },
        .green  = { .offset =  8, .length = 8, },
-       .blue   = { .offset = 16, .length = 8, },
+       .blue   = { .offset =  0, .length = 8, },
        .transp = { .offset =  0, .length = 0, },
        .bits_per_pixel = 24,
 };
 
-static struct ipu_rgb def_bgr_24 = {
-       .red    = { .offset = 16, .length = 8, },
+static const struct ipu_rgb def_bgr_24 = {
+       .red    = { .offset =  0, .length = 8, },
        .green  = { .offset =  8, .length = 8, },
-       .blue   = { .offset =  0, .length = 8, },
+       .blue   = { .offset = 16, .length = 8, },
        .transp = { .offset =  0, .length = 0, },
        .bits_per_pixel = 24,
 };
 
-static struct ipu_rgb def_rgb_16 = {
+static const struct ipu_rgb def_rgb_16 = {
        .red    = { .offset = 11, .length = 5, },
        .green  = { .offset =  5, .length = 6, },
        .blue   = { .offset =  0, .length = 5, },
@@ -322,6 +324,14 @@ static struct ipu_rgb def_rgb_16 = {
        .bits_per_pixel = 16,
 };
 
+static const struct ipu_rgb def_bgr_16 = {
+       .red    = { .offset =  0, .length = 5, },
+       .green  = { .offset =  5, .length = 6, },
+       .blue   = { .offset = 11, .length = 5, },
+       .transp = { .offset =  0, .length = 0, },
+       .bits_per_pixel = 16,
+};
+
 #define Y_OFFSET(pix, x, y)    ((x) + pix->width * (y))
 #define U_OFFSET(pix, x, y)    ((pix->width * pix->height) + \
                                        (pix->width * (y) / 4) + (x) / 2)
@@ -329,17 +339,17 @@ static struct ipu_rgb def_rgb_16 = {
                                        (pix->width * pix->height / 4) + \
                                        (pix->width * (y) / 4) + (x) / 2)
 
-int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
+int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 drm_fourcc)
 {
-       switch (pixelformat) {
-       case V4L2_PIX_FMT_YUV420:
-       case V4L2_PIX_FMT_YVU420:
+       switch (drm_fourcc) {
+       case DRM_FORMAT_YUV420:
+       case DRM_FORMAT_YVU420:
                /* pix format */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 2);
                /* burst size */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 63);
                break;
-       case V4L2_PIX_FMT_UYVY:
+       case DRM_FORMAT_UYVY:
                /* bits/pixel */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3);
                /* pix format */
@@ -347,7 +357,7 @@ int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
                /* burst size */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31);
                break;
-       case V4L2_PIX_FMT_YUYV:
+       case DRM_FORMAT_YUYV:
                /* bits/pixel */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3);
                /* pix format */
@@ -355,20 +365,25 @@ int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
                /* burst size */
                ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31);
                break;
-       case V4L2_PIX_FMT_RGB32:
-               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_32);
+       case DRM_FORMAT_ABGR8888:
+       case DRM_FORMAT_XBGR8888:
+               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_32);
                break;
-       case V4L2_PIX_FMT_RGB565:
-               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_16);
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_XRGB8888:
+               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_32);
                break;
-       case V4L2_PIX_FMT_BGR32:
-               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_32);
+       case DRM_FORMAT_BGR888:
+               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_24);
                break;
-       case V4L2_PIX_FMT_RGB24:
+       case DRM_FORMAT_RGB888:
                ipu_cpmem_set_format_rgb(cpmem, &def_rgb_24);
                break;
-       case V4L2_PIX_FMT_BGR24:
-               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_24);
+       case DRM_FORMAT_RGB565:
+               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_16);
+               break;
+       case DRM_FORMAT_BGR565:
+               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_16);
                break;
        default:
                return -EINVAL;
@@ -378,6 +393,79 @@ int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
 }
 EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt);
 
+/*
+ * The V4L2 spec defines packed RGB formats in memory byte order, which from
+ * point of view of the IPU corresponds to little-endian words with the first
+ * component in the least significant bits.
+ * The DRM pixel formats and IPU internal representation are ordered the other
+ * way around, with the first named component ordered at the most significant
+ * bits. Further, V4L2 formats are not well defined:
+ *     http://linuxtv.org/downloads/v4l-dvb-apis/packed-rgb.html
+ * We choose the interpretation which matches GStreamer behavior.
+ */
+static int v4l2_pix_fmt_to_drm_fourcc(u32 pixelformat)
+{
+       switch (pixelformat) {
+       case V4L2_PIX_FMT_RGB565:
+               /*
+                * Here we choose the 'corrected' interpretation of RGBP, a
+                * little-endian 16-bit word with the red component at the most
+                * significant bits:
+                * g[2:0]b[4:0] r[4:0]g[5:3] <=> [16:0] R:G:B
+                */
+               return DRM_FORMAT_RGB565;
+       case V4L2_PIX_FMT_BGR24:
+               /* B G R <=> [24:0] R:G:B */
+               return DRM_FORMAT_RGB888;
+       case V4L2_PIX_FMT_RGB24:
+               /* R G B <=> [24:0] B:G:R */
+               return DRM_FORMAT_BGR888;
+       case V4L2_PIX_FMT_BGR32:
+               /* B G R A <=> [32:0] A:B:G:R */
+               return DRM_FORMAT_XRGB8888;
+       case V4L2_PIX_FMT_RGB32:
+               /* R G B A <=> [32:0] A:B:G:R */
+               return DRM_FORMAT_XBGR8888;
+       case V4L2_PIX_FMT_UYVY:
+               return DRM_FORMAT_UYVY;
+       case V4L2_PIX_FMT_YUYV:
+               return DRM_FORMAT_YUYV;
+       case V4L2_PIX_FMT_YUV420:
+               return DRM_FORMAT_YUV420;
+       case V4L2_PIX_FMT_YVU420:
+               return DRM_FORMAT_YVU420;
+       }
+
+       return -EINVAL;
+}
+
+enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc)
+{
+       switch (drm_fourcc) {
+       case DRM_FORMAT_RGB565:
+       case DRM_FORMAT_BGR565:
+       case DRM_FORMAT_RGB888:
+       case DRM_FORMAT_BGR888:
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_XBGR8888:
+       case DRM_FORMAT_RGBX8888:
+       case DRM_FORMAT_BGRX8888:
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_ABGR8888:
+       case DRM_FORMAT_RGBA8888:
+       case DRM_FORMAT_BGRA8888:
+               return IPUV3_COLORSPACE_RGB;
+       case DRM_FORMAT_YUYV:
+       case DRM_FORMAT_UYVY:
+       case DRM_FORMAT_YUV420:
+       case DRM_FORMAT_YVU420:
+               return IPUV3_COLORSPACE_YUV;
+       default:
+               return IPUV3_COLORSPACE_UNKNOWN;
+       }
+}
+EXPORT_SYMBOL_GPL(ipu_drm_fourcc_to_colorspace);
+
 int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
                struct ipu_image *image)
 {
@@ -392,7 +480,7 @@ int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
                        image->rect.height);
        ipu_cpmem_set_stride(cpmem, pix->bytesperline);
 
-       ipu_cpmem_set_fmt(cpmem, pix->pixelformat);
+       ipu_cpmem_set_fmt(cpmem, v4l2_pix_fmt_to_drm_fourcc(pix->pixelformat));
 
        switch (pix->pixelformat) {
        case V4L2_PIX_FMT_YUV420:
@@ -610,24 +698,29 @@ int ipu_idmac_enable_channel(struct ipuv3_channel *channel)
 }
 EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel);
 
-int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
+int ipu_idmac_wait_busy(struct ipuv3_channel *channel, int ms)
 {
        struct ipu_soc *ipu = channel->ipu;
-       u32 val;
-       unsigned long flags;
        unsigned long timeout;
 
-       timeout = jiffies + msecs_to_jiffies(50);
+       timeout = jiffies + msecs_to_jiffies(ms);
        while (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(channel->num)) &
                        idma_mask(channel->num)) {
-               if (time_after(jiffies, timeout)) {
-                       dev_warn(ipu->dev, "disabling busy idmac channel %d\n",
-                                       channel->num);
-                       break;
-               }
+               if (time_after(jiffies, timeout))
+                       return -ETIMEDOUT;
                cpu_relax();
        }
 
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_wait_busy);
+
+int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
+{
+       struct ipu_soc *ipu = channel->ipu;
+       u32 val;
+       unsigned long flags;
+
        spin_lock_irqsave(&ipu->lock, flags);
 
        /* Disable DMA channel(s) */
@@ -888,7 +981,7 @@ static const struct ipu_platform_reg client_reg[] = {
                        .dc = 5,
                        .dp = IPU_DP_FLOW_SYNC_BG,
                        .dma[0] = IPUV3_CHANNEL_MEM_BG_SYNC,
-                       .dma[1] = -EINVAL,
+                       .dma[1] = IPUV3_CHANNEL_MEM_FG_SYNC,
                },
                .name = "imx-ipuv3-crtc",
        }, {
index 21bf1c8065288edb83c34108f65885f264185434..1a6e06d1ebafccb9d127fa54de64937b206e95fd 100644 (file)
@@ -91,6 +91,7 @@ enum ipu_dc_map {
        IPU_DC_MAP_RGB565,
        IPU_DC_MAP_GBR24, /* TVEv2 */
        IPU_DC_MAP_BGR666,
+       IPU_DC_MAP_BGR24,
 };
 
 struct ipu_dc {
@@ -152,6 +153,8 @@ static int ipu_pixfmt_to_map(u32 fmt)
                return IPU_DC_MAP_GBR24;
        case V4L2_PIX_FMT_BGR666:
                return IPU_DC_MAP_BGR666;
+       case V4L2_PIX_FMT_BGR24:
+               return IPU_DC_MAP_BGR24;
        default:
                return -EINVAL;
        }
@@ -395,6 +398,12 @@ int ipu_dc_init(struct ipu_soc *ipu, struct device *dev,
        ipu_dc_map_config(priv, IPU_DC_MAP_BGR666, 1, 11, 0xfc); /* green */
        ipu_dc_map_config(priv, IPU_DC_MAP_BGR666, 2, 17, 0xfc); /* red */
 
+       /* bgr24 */
+       ipu_dc_map_clear(priv, IPU_DC_MAP_BGR24);
+       ipu_dc_map_config(priv, IPU_DC_MAP_BGR24, 2, 7, 0xff); /* red */
+       ipu_dc_map_config(priv, IPU_DC_MAP_BGR24, 1, 15, 0xff); /* green */
+       ipu_dc_map_config(priv, IPU_DC_MAP_BGR24, 0, 23, 0xff); /* blue */
+
        return 0;
 }
 
index 2e97c33b81e7ca32ed9498aa05f0be1b470bb961..98070dd8c92057c85b6a9aea1b9236fbb504b89f 100644 (file)
@@ -307,13 +307,13 @@ int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc,
                goto out;
        }
 
-       /* Always allocate at least 128*4 bytes (2 slots) */
-       if (slots < 2)
-               slots = 2;
-
        /* For the MEM_BG channel, first try to allocate twice the slots */
        if (dmfc->data->ipu_channel == IPUV3_CHANNEL_MEM_BG_SYNC)
                segment = dmfc_find_slots(priv, slots * 2);
+       else if (slots < 2)
+               /* Always allocate at least 128*4 bytes (2 slots) */
+               slots = 2;
+
        if (segment >= 0)
                slots *= 2;
        else
index 9e73e8d8c9aaa350267ac25f0926a5cd8d7c6416..794dfc16dca3b937079375d54619c3930b811f51 100644 (file)
 #include <drm/drm_crtc_helper.h>
 #include <linux/fb.h>
 #include <linux/clk.h>
+#include <linux/errno.h>
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_fb_cma_helper.h>
 
 #include "ipu-v3/imx-ipu-v3.h"
 #include "imx-drm.h"
+#include "ipuv3-plane.h"
 
 #define DRIVER_DESC            "i.MX IPUv3 Graphics"
 
-struct ipu_framebuffer {
-       struct drm_framebuffer  base;
-       void                    *virt;
-       dma_addr_t              phys;
-       size_t                  len;
-};
-
 struct ipu_crtc {
        struct device           *dev;
        struct drm_crtc         base;
        struct imx_drm_crtc     *imx_crtc;
-       struct ipuv3_channel    *ipu_ch;
+
+       /* plane[0] is the full plane, plane[1] is the partial plane */
+       struct ipu_plane        *plane[2];
+
        struct ipu_dc           *dc;
-       struct ipu_dp           *dp;
-       struct dmfc_channel     *dmfc;
        struct ipu_di           *di;
        int                     enabled;
        struct drm_pending_vblank_event *page_flip_event;
@@ -61,35 +57,14 @@ struct ipu_crtc {
 
 #define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base)
 
-static int calc_vref(struct drm_display_mode *mode)
-{
-       unsigned long htotal, vtotal;
-
-       htotal = mode->htotal;
-       vtotal = mode->vtotal;
-
-       if (!htotal || !vtotal)
-               return 60;
-
-       return mode->clock * 1000 / vtotal / htotal;
-}
-
-static int calc_bandwidth(struct drm_display_mode *mode, unsigned int vref)
-{
-       return mode->hdisplay * mode->vdisplay * vref;
-}
-
 static void ipu_fb_enable(struct ipu_crtc *ipu_crtc)
 {
        if (ipu_crtc->enabled)
                return;
 
        ipu_di_enable(ipu_crtc->di);
-       ipu_dmfc_enable_channel(ipu_crtc->dmfc);
-       ipu_idmac_enable_channel(ipu_crtc->ipu_ch);
        ipu_dc_enable_channel(ipu_crtc->dc);
-       if (ipu_crtc->dp)
-               ipu_dp_enable_channel(ipu_crtc->dp);
+       ipu_plane_enable(ipu_crtc->plane[0]);
 
        ipu_crtc->enabled = 1;
 }
@@ -99,11 +74,8 @@ static void ipu_fb_disable(struct ipu_crtc *ipu_crtc)
        if (!ipu_crtc->enabled)
                return;
 
-       if (ipu_crtc->dp)
-               ipu_dp_disable_channel(ipu_crtc->dp);
+       ipu_plane_disable(ipu_crtc->plane[0]);
        ipu_dc_disable_channel(ipu_crtc->dc);
-       ipu_idmac_disable_channel(ipu_crtc->ipu_ch);
-       ipu_dmfc_disable_channel(ipu_crtc->dmfc);
        ipu_di_disable(ipu_crtc->di);
 
        ipu_crtc->enabled = 0;
@@ -159,33 +131,6 @@ static const struct drm_crtc_funcs ipu_crtc_funcs = {
        .page_flip = ipu_page_flip,
 };
 
-static int ipu_drm_set_base(struct drm_crtc *crtc, int x, int y)
-{
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-       struct drm_gem_cma_object *cma_obj;
-       struct drm_framebuffer *fb = crtc->fb;
-       unsigned long phys;
-
-       cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
-       if (!cma_obj) {
-               DRM_LOG_KMS("entry is null.\n");
-               return -EFAULT;
-       }
-
-       phys = cma_obj->paddr;
-       phys += x * (fb->bits_per_pixel >> 3);
-       phys += y * fb->pitches[0];
-
-       dev_dbg(ipu_crtc->dev, "%s: phys: 0x%lx\n", __func__, phys);
-       dev_dbg(ipu_crtc->dev, "%s: xy: %dx%d\n", __func__, x, y);
-
-       ipu_cpmem_set_stride(ipu_get_cpmem(ipu_crtc->ipu_ch), fb->pitches[0]);
-       ipu_cpmem_set_buffer(ipu_get_cpmem(ipu_crtc->ipu_ch),
-                         0, phys);
-
-       return 0;
-}
-
 static int ipu_crtc_mode_set(struct drm_crtc *crtc,
                               struct drm_display_mode *orig_mode,
                               struct drm_display_mode *mode,
@@ -193,41 +138,15 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
                               struct drm_framebuffer *old_fb)
 {
        struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-       struct drm_framebuffer *fb = ipu_crtc->base.fb;
        int ret;
        struct ipu_di_signal_cfg sig_cfg = {};
        u32 out_pixel_fmt;
-       struct ipu_ch_param __iomem *cpmem = ipu_get_cpmem(ipu_crtc->ipu_ch);
-       int bpp;
-       u32 v4l2_fmt;
 
        dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
                        mode->hdisplay);
        dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
                        mode->vdisplay);
 
-       ipu_ch_param_zero(cpmem);
-
-       switch (fb->pixel_format) {
-       case DRM_FORMAT_XRGB8888:
-       case DRM_FORMAT_ARGB8888:
-               v4l2_fmt = V4L2_PIX_FMT_RGB32;
-               bpp = 32;
-               break;
-       case DRM_FORMAT_RGB565:
-               v4l2_fmt = V4L2_PIX_FMT_RGB565;
-               bpp = 16;
-               break;
-       case DRM_FORMAT_RGB888:
-               v4l2_fmt = V4L2_PIX_FMT_RGB24;
-               bpp = 24;
-               break;
-       default:
-               dev_err(ipu_crtc->dev, "unsupported pixel format 0x%08x\n",
-                               fb->pixel_format);
-               return -EINVAL;
-       }
-
        out_pixel_fmt = ipu_crtc->interface_pix_fmt;
 
        if (mode->flags & DRM_MODE_FLAG_INTERLACE)
@@ -257,18 +176,6 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
        sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
        sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin;
 
-       if (ipu_crtc->dp) {
-               ret = ipu_dp_setup_channel(ipu_crtc->dp, IPUV3_COLORSPACE_RGB,
-                               IPUV3_COLORSPACE_RGB);
-               if (ret) {
-                       dev_err(ipu_crtc->dev,
-                               "initializing display processor failed with %d\n",
-                               ret);
-                       return ret;
-               }
-               ipu_dp_set_global_alpha(ipu_crtc->dp, 1, 0, 1);
-       }
-
        ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, sig_cfg.interlaced,
                        out_pixel_fmt, mode->hdisplay);
        if (ret) {
@@ -285,30 +192,9 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
                return ret;
        }
 
-       ipu_cpmem_set_resolution(cpmem, mode->hdisplay, mode->vdisplay);
-       ipu_cpmem_set_fmt(cpmem, v4l2_fmt);
-       ipu_cpmem_set_high_priority(ipu_crtc->ipu_ch);
-
-       ret = ipu_dmfc_init_channel(ipu_crtc->dmfc, mode->hdisplay);
-       if (ret) {
-               dev_err(ipu_crtc->dev,
-                               "initializing dmfc channel failed with %d\n",
-                               ret);
-               return ret;
-       }
-
-       ret = ipu_dmfc_alloc_bandwidth(ipu_crtc->dmfc,
-                       calc_bandwidth(mode, calc_vref(mode)), 64);
-       if (ret) {
-               dev_err(ipu_crtc->dev,
-                               "allocating dmfc bandwidth failed with %d\n",
-                               ret);
-               return ret;
-       }
-
-       ipu_drm_set_base(crtc, x, y);
-
-       return 0;
+       return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode, crtc->fb,
+                                 0, 0, mode->hdisplay, mode->vdisplay,
+                                 x, y, mode->hdisplay, mode->vdisplay);
 }
 
 static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc)
@@ -332,7 +218,7 @@ static irqreturn_t ipu_irq_handler(int irq, void *dev_id)
 
        if (ipu_crtc->newfb) {
                ipu_crtc->newfb = NULL;
-               ipu_drm_set_base(&ipu_crtc->base, 0, 0);
+               ipu_plane_set_base(ipu_crtc->plane[0], ipu_crtc->base.fb, 0, 0);
                ipu_crtc_handle_pageflip(ipu_crtc);
        }
 
@@ -370,10 +256,6 @@ static struct drm_crtc_helper_funcs ipu_helper_funcs = {
 
 static int ipu_enable_vblank(struct drm_crtc *crtc)
 {
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-
-       enable_irq(ipu_crtc->irq);
-
        return 0;
 }
 
@@ -381,7 +263,8 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
 {
        struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
 
-       disable_irq(ipu_crtc->irq);
+       ipu_crtc->page_flip_event = NULL;
+       ipu_crtc->newfb = NULL;
 }
 
 static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
@@ -418,12 +301,8 @@ static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = {
 
 static void ipu_put_resources(struct ipu_crtc *ipu_crtc)
 {
-       if (!IS_ERR_OR_NULL(ipu_crtc->ipu_ch))
-               ipu_idmac_put(ipu_crtc->ipu_ch);
-       if (!IS_ERR_OR_NULL(ipu_crtc->dmfc))
-               ipu_dmfc_put(ipu_crtc->dmfc);
-       if (!IS_ERR_OR_NULL(ipu_crtc->dp))
-               ipu_dp_put(ipu_crtc->dp);
+       if (!IS_ERR_OR_NULL(ipu_crtc->dc))
+               ipu_dc_put(ipu_crtc->dc);
        if (!IS_ERR_OR_NULL(ipu_crtc->di))
                ipu_di_put(ipu_crtc->di);
 }
@@ -434,32 +313,12 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
        struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
        int ret;
 
-       ipu_crtc->ipu_ch = ipu_idmac_get(ipu, pdata->dma[0]);
-       if (IS_ERR(ipu_crtc->ipu_ch)) {
-               ret = PTR_ERR(ipu_crtc->ipu_ch);
-               goto err_out;
-       }
-
        ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc);
        if (IS_ERR(ipu_crtc->dc)) {
                ret = PTR_ERR(ipu_crtc->dc);
                goto err_out;
        }
 
-       ipu_crtc->dmfc = ipu_dmfc_get(ipu, pdata->dma[0]);
-       if (IS_ERR(ipu_crtc->dmfc)) {
-               ret = PTR_ERR(ipu_crtc->dmfc);
-               goto err_out;
-       }
-
-       if (pdata->dp >= 0) {
-               ipu_crtc->dp = ipu_dp_get(ipu, pdata->dp);
-               if (IS_ERR(ipu_crtc->dp)) {
-                       ret = PTR_ERR(ipu_crtc->dp);
-                       goto err_out;
-               }
-       }
-
        ipu_crtc->di = ipu_di_get(ipu, pdata->di);
        if (IS_ERR(ipu_crtc->di)) {
                ret = PTR_ERR(ipu_crtc->di);
@@ -477,7 +336,9 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
                struct ipu_client_platformdata *pdata)
 {
        struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
+       int dp = -EINVAL;
        int ret;
+       int id;
 
        ret = ipu_get_resources(ipu_crtc, pdata);
        if (ret) {
@@ -495,19 +356,42 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
                goto err_put_resources;
        }
 
-       ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch,
-                       IPU_IRQ_EOF);
+       if (pdata->dp >= 0)
+               dp = IPU_DP_FLOW_SYNC_BG;
+       id = imx_drm_crtc_id(ipu_crtc->imx_crtc);
+       ipu_crtc->plane[0] = ipu_plane_init(ipu_crtc->base.dev, ipu,
+                                           pdata->dma[0], dp, BIT(id), true);
+       ret = ipu_plane_get_resources(ipu_crtc->plane[0]);
+       if (ret) {
+               dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n",
+                       ret);
+               goto err_remove_crtc;
+       }
+
+       /* If this crtc is using the DP, add an overlay plane */
+       if (pdata->dp >= 0 && pdata->dma[1] > 0) {
+               ipu_crtc->plane[1] = ipu_plane_init(ipu_crtc->base.dev, ipu,
+                                                   pdata->dma[1],
+                                                   IPU_DP_FLOW_SYNC_FG,
+                                                   BIT(id), false);
+               if (IS_ERR(ipu_crtc->plane[1]))
+                       ipu_crtc->plane[1] = NULL;
+       }
+
+       ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
        ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
                        "imx_drm", ipu_crtc);
        if (ret < 0) {
                dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
-               goto err_put_resources;
+               goto err_put_plane_res;
        }
 
-       disable_irq(ipu_crtc->irq);
-
        return 0;
 
+err_put_plane_res:
+       ipu_plane_put_resources(ipu_crtc->plane[0]);
+err_remove_crtc:
+       imx_drm_remove_crtc(ipu_crtc->imx_crtc);
 err_put_resources:
        ipu_put_resources(ipu_crtc);
 
@@ -548,6 +432,7 @@ static int ipu_drm_remove(struct platform_device *pdev)
 
        imx_drm_remove_crtc(ipu_crtc->imx_crtc);
 
+       ipu_plane_put_resources(ipu_crtc->plane[0]);
        ipu_put_resources(ipu_crtc);
 
        return 0;
diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c
new file mode 100644 (file)
index 0000000..d97454a
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * i.MX IPUv3 DP Overlay Planes
+ *
+ * Copyright (C) 2013 Philipp Zabel, Pengutronix
+ *
+ * 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.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include "ipu-v3/imx-ipu-v3.h"
+#include "ipuv3-plane.h"
+
+#define to_ipu_plane(x)        container_of(x, struct ipu_plane, base)
+
+static const uint32_t ipu_plane_formats[] = {
+       DRM_FORMAT_XRGB1555,
+       DRM_FORMAT_XBGR1555,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_ABGR8888,
+       DRM_FORMAT_XBGR8888,
+       DRM_FORMAT_YUYV,
+       DRM_FORMAT_YVYU,
+       DRM_FORMAT_YUV420,
+       DRM_FORMAT_YVU420,
+};
+
+int ipu_plane_irq(struct ipu_plane *ipu_plane)
+{
+       return ipu_idmac_channel_irq(ipu_plane->ipu, ipu_plane->ipu_ch,
+                                    IPU_IRQ_EOF);
+}
+
+static int calc_vref(struct drm_display_mode *mode)
+{
+       unsigned long htotal, vtotal;
+
+       htotal = mode->htotal;
+       vtotal = mode->vtotal;
+
+       if (!htotal || !vtotal)
+               return 60;
+
+       return DIV_ROUND_UP(mode->clock * 1000, vtotal * htotal);
+}
+
+static inline int calc_bandwidth(int width, int height, unsigned int vref)
+{
+       return width * height * vref;
+}
+
+int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb,
+                      int x, int y)
+{
+       struct ipu_ch_param __iomem *cpmem;
+       struct drm_gem_cma_object *cma_obj;
+
+       cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+       if (!cma_obj) {
+               DRM_LOG_KMS("entry is null.\n");
+               return -EFAULT;
+       }
+
+       dev_dbg(ipu_plane->base.dev->dev, "phys = 0x%x, x = %d, y = %d",
+               cma_obj->paddr, x, y);
+
+       cpmem = ipu_get_cpmem(ipu_plane->ipu_ch);
+       ipu_cpmem_set_stride(cpmem, fb->pitches[0]);
+       ipu_cpmem_set_buffer(cpmem, 0, cma_obj->paddr + fb->offsets[0] +
+                            fb->pitches[0] * y + x);
+
+       return 0;
+}
+
+int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
+                      struct drm_display_mode *mode,
+                      struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                      unsigned int crtc_w, unsigned int crtc_h,
+                      uint32_t src_x, uint32_t src_y,
+                      uint32_t src_w, uint32_t src_h)
+{
+       struct ipu_ch_param __iomem *cpmem;
+       struct device *dev = ipu_plane->base.dev->dev;
+       int ret;
+
+       /* no scaling */
+       if (src_w != crtc_w || src_h != crtc_h)
+               return -EINVAL;
+
+       /* clip to crtc bounds */
+       if (crtc_x < 0) {
+               if (-crtc_x > crtc_w)
+                       return -EINVAL;
+               src_x += -crtc_x;
+               src_w -= -crtc_x;
+               crtc_w -= -crtc_x;
+               crtc_x = 0;
+       }
+       if (crtc_y < 0) {
+               if (-crtc_y > crtc_h)
+                       return -EINVAL;
+               src_y += -crtc_y;
+               src_h -= -crtc_y;
+               crtc_h -= -crtc_y;
+               crtc_y = 0;
+       }
+       if (crtc_x + crtc_w > mode->hdisplay) {
+               if (crtc_x > mode->hdisplay)
+                       return -EINVAL;
+               crtc_w = mode->hdisplay - crtc_x;
+               src_w = crtc_w;
+       }
+       if (crtc_y + crtc_h > mode->vdisplay) {
+               if (crtc_y > mode->vdisplay)
+                       return -EINVAL;
+               crtc_h = mode->vdisplay - crtc_y;
+               src_h = crtc_h;
+       }
+       /* full plane minimum width is 13 pixels */
+       if (crtc_w < 13 && (ipu_plane->dp_flow != IPU_DP_FLOW_SYNC_FG))
+               return -EINVAL;
+       if (crtc_h < 2)
+               return -EINVAL;
+
+       switch (ipu_plane->dp_flow) {
+       case IPU_DP_FLOW_SYNC_BG:
+               ret = ipu_dp_setup_channel(ipu_plane->dp,
+                               IPUV3_COLORSPACE_RGB,
+                               IPUV3_COLORSPACE_RGB);
+               if (ret) {
+                       dev_err(dev,
+                               "initializing display processor failed with %d\n",
+                               ret);
+                       return ret;
+               }
+               ipu_dp_set_global_alpha(ipu_plane->dp, 1, 0, 1);
+               break;
+       case IPU_DP_FLOW_SYNC_FG:
+               ipu_dp_setup_channel(ipu_plane->dp,
+                               ipu_drm_fourcc_to_colorspace(fb->pixel_format),
+                               IPUV3_COLORSPACE_UNKNOWN);
+               ipu_dp_set_window_pos(ipu_plane->dp, crtc_x, crtc_y);
+               break;
+       }
+
+       ret = ipu_dmfc_init_channel(ipu_plane->dmfc, crtc_w);
+       if (ret) {
+               dev_err(dev, "initializing dmfc channel failed with %d\n", ret);
+               return ret;
+       }
+
+       ret = ipu_dmfc_alloc_bandwidth(ipu_plane->dmfc,
+                       calc_bandwidth(crtc_w, crtc_h,
+                                      calc_vref(mode)), 64);
+       if (ret) {
+               dev_err(dev, "allocating dmfc bandwidth failed with %d\n", ret);
+               return ret;
+       }
+
+       cpmem = ipu_get_cpmem(ipu_plane->ipu_ch);
+       ipu_ch_param_zero(cpmem);
+       ipu_cpmem_set_resolution(cpmem, src_w, src_h);
+       ret = ipu_cpmem_set_fmt(cpmem, fb->pixel_format);
+       if (ret < 0) {
+               dev_err(dev, "unsupported pixel format 0x%08x\n",
+                       fb->pixel_format);
+               return ret;
+       }
+       ipu_cpmem_set_high_priority(ipu_plane->ipu_ch);
+
+       ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+void ipu_plane_put_resources(struct ipu_plane *ipu_plane)
+{
+       if (!IS_ERR_OR_NULL(ipu_plane->dp))
+               ipu_dp_put(ipu_plane->dp);
+       if (!IS_ERR_OR_NULL(ipu_plane->dmfc))
+               ipu_dmfc_put(ipu_plane->dmfc);
+       if (!IS_ERR_OR_NULL(ipu_plane->ipu_ch))
+               ipu_idmac_put(ipu_plane->ipu_ch);
+}
+
+int ipu_plane_get_resources(struct ipu_plane *ipu_plane)
+{
+       int ret;
+
+       ipu_plane->ipu_ch = ipu_idmac_get(ipu_plane->ipu, ipu_plane->dma);
+       if (IS_ERR(ipu_plane->ipu_ch)) {
+               ret = PTR_ERR(ipu_plane->ipu_ch);
+               DRM_ERROR("failed to get idmac channel: %d\n", ret);
+               return ret;
+       }
+
+       ipu_plane->dmfc = ipu_dmfc_get(ipu_plane->ipu, ipu_plane->dma);
+       if (IS_ERR(ipu_plane->dmfc)) {
+               ret = PTR_ERR(ipu_plane->dmfc);
+               DRM_ERROR("failed to get dmfc: ret %d\n", ret);
+               goto err_out;
+       }
+
+       if (ipu_plane->dp_flow >= 0) {
+               ipu_plane->dp = ipu_dp_get(ipu_plane->ipu, ipu_plane->dp_flow);
+               if (IS_ERR(ipu_plane->dp)) {
+                       ret = PTR_ERR(ipu_plane->dp);
+                       DRM_ERROR("failed to get dp flow: %d\n", ret);
+                       goto err_out;
+               }
+       }
+
+       return 0;
+err_out:
+       ipu_plane_put_resources(ipu_plane);
+
+       return ret;
+}
+
+void ipu_plane_enable(struct ipu_plane *ipu_plane)
+{
+       ipu_dmfc_enable_channel(ipu_plane->dmfc);
+       ipu_idmac_enable_channel(ipu_plane->ipu_ch);
+       if (ipu_plane->dp)
+               ipu_dp_enable_channel(ipu_plane->dp);
+
+       ipu_plane->enabled = true;
+}
+
+void ipu_plane_disable(struct ipu_plane *ipu_plane)
+{
+       ipu_plane->enabled = false;
+
+       ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50);
+
+       if (ipu_plane->dp)
+               ipu_dp_disable_channel(ipu_plane->dp);
+       ipu_idmac_disable_channel(ipu_plane->ipu_ch);
+       ipu_dmfc_disable_channel(ipu_plane->dmfc);
+}
+
+static void ipu_plane_dpms(struct ipu_plane *ipu_plane, int mode)
+{
+       bool enable;
+
+       DRM_DEBUG_KMS("mode = %d", mode);
+
+       enable = (mode == DRM_MODE_DPMS_ON);
+
+       if (enable == ipu_plane->enabled)
+               return;
+
+       if (enable) {
+               ipu_plane_enable(ipu_plane);
+       } else {
+               ipu_plane_disable(ipu_plane);
+
+               ipu_idmac_put(ipu_plane->ipu_ch);
+               ipu_dmfc_put(ipu_plane->dmfc);
+               ipu_dp_put(ipu_plane->dp);
+       }
+}
+
+/*
+ * drm_plane API
+ */
+
+static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+                           struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                           unsigned int crtc_w, unsigned int crtc_h,
+                           uint32_t src_x, uint32_t src_y,
+                           uint32_t src_w, uint32_t src_h)
+{
+       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
+       int ret = 0;
+
+       DRM_DEBUG_KMS("plane - %p\n", plane);
+
+       if (!ipu_plane->enabled)
+               ret = ipu_plane_get_resources(ipu_plane);
+       if (ret < 0)
+               return ret;
+
+       ret = ipu_plane_mode_set(ipu_plane, crtc, &crtc->hwmode, fb,
+                       crtc_x, crtc_y, crtc_w, crtc_h,
+                       src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16);
+       if (ret < 0) {
+               ipu_plane_put_resources(ipu_plane);
+               return ret;
+       }
+
+       if (crtc != plane->crtc)
+               dev_info(plane->dev->dev, "crtc change: %p -> %p\n",
+                               plane->crtc, crtc);
+       plane->crtc = crtc;
+
+       ipu_plane_dpms(ipu_plane, DRM_MODE_DPMS_ON);
+
+       return 0;
+}
+
+static int ipu_disable_plane(struct drm_plane *plane)
+{
+       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
+
+       DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+
+       ipu_plane_dpms(ipu_plane, DRM_MODE_DPMS_OFF);
+
+       ipu_plane_put_resources(ipu_plane);
+
+       return 0;
+}
+
+static void ipu_plane_destroy(struct drm_plane *plane)
+{
+       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
+
+       DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+
+       ipu_disable_plane(plane);
+       drm_plane_cleanup(plane);
+       kfree(ipu_plane);
+}
+
+static struct drm_plane_funcs ipu_plane_funcs = {
+       .update_plane   = ipu_update_plane,
+       .disable_plane  = ipu_disable_plane,
+       .destroy        = ipu_plane_destroy,
+};
+
+struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
+                                int dma, int dp, unsigned int possible_crtcs,
+                                bool priv)
+{
+       struct ipu_plane *ipu_plane;
+       int ret;
+
+       DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n",
+                     dma, dp, possible_crtcs);
+
+       ipu_plane = kzalloc(sizeof(*ipu_plane), GFP_KERNEL);
+       if (!ipu_plane) {
+               DRM_ERROR("failed to allocate plane\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       ipu_plane->ipu = ipu;
+       ipu_plane->dma = dma;
+       ipu_plane->dp_flow = dp;
+
+       ret = drm_plane_init(dev, &ipu_plane->base, possible_crtcs,
+                            &ipu_plane_funcs, ipu_plane_formats,
+                            ARRAY_SIZE(ipu_plane_formats),
+                            priv);
+       if (ret) {
+               DRM_ERROR("failed to initialize plane\n");
+               kfree(ipu_plane);
+               return ERR_PTR(ret);
+       }
+
+       return ipu_plane;
+}
diff --git a/drivers/staging/imx-drm/ipuv3-plane.h b/drivers/staging/imx-drm/ipuv3-plane.h
new file mode 100644 (file)
index 0000000..c0aae5b
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __IPUV3_PLANE_H__
+#define __IPUV3_PLANE_H__
+
+#include <drm/drm_crtc.h> /* drm_plane */
+
+struct drm_plane;
+struct drm_device;
+struct ipu_soc;
+struct drm_crtc;
+struct drm_framebuffer;
+
+struct ipuv3_channel;
+struct dmfc_channel;
+struct ipu_dp;
+
+struct ipu_plane {
+       struct drm_plane        base;
+
+       struct ipu_soc          *ipu;
+       struct ipuv3_channel    *ipu_ch;
+       struct dmfc_channel     *dmfc;
+       struct ipu_dp           *dp;
+
+       int                     dma;
+       int                     dp_flow;
+
+       int                     x;
+       int                     y;
+
+       bool                    enabled;
+};
+
+struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
+                                int dma, int dp, unsigned int possible_crtcs,
+                                bool priv);
+
+/* Init IDMAC, DMFC, DP */
+int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc,
+                      struct drm_display_mode *mode,
+                      struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                      unsigned int crtc_w, unsigned int crtc_h,
+                      uint32_t src_x, uint32_t src_y, uint32_t src_w,
+                      uint32_t src_h);
+
+void ipu_plane_enable(struct ipu_plane *plane);
+void ipu_plane_disable(struct ipu_plane *plane);
+int ipu_plane_set_base(struct ipu_plane *plane, struct drm_framebuffer *fb,
+                      int x, int y);
+
+int ipu_plane_get_resources(struct ipu_plane *plane);
+void ipu_plane_put_resources(struct ipu_plane *plane);
+
+int ipu_plane_irq(struct ipu_plane *plane);
+
+#endif
index ddd2e7390b4611b9df23d282874210e3b915f312..a84ee6303368422468b4656e27d62d098c303eeb 100644 (file)
@@ -604,9 +604,7 @@ static int eucr_probe(struct usb_interface *intf,
        if (!(MiscReg03 & 0x02)) {
                result = -ENODEV;
                quiesce_and_remove_host(us);
-               pr_info("keucr: The driver only supports SM/MS card. "
-                       "To use SD card, "
-                       "please build driver/usb/storage/ums-eneub6250.ko\n");
+               pr_info("keucr: The driver only supports SM/MS card. To use SD card, please build driver/usb/storage/ums-eneub6250.ko\n");
                goto BadDevice;
        }
 
diff --git a/drivers/staging/ktap/Kconfig b/drivers/staging/ktap/Kconfig
new file mode 100644 (file)
index 0000000..21f8d2e
--- /dev/null
@@ -0,0 +1,21 @@
+config KTAP
+       tristate "a programable dynamic tracing tool for Linux"
+       depends on PERF_EVENTS && EVENT_TRACING
+       default n
+       help
+         ktap is a new script-based dynamic tracing tool for Linux,
+         it uses a scripting language and lets users trace the
+         Linux kernel dynamically. ktap is designed to give
+         operational insights with interoperability that allow
+         users to tune, troubleshoot and extend kernel and application.
+         It's similar with Linux Systemtap and Solaris Dtrace.
+
+         ktap have different design principles from Linux mainstream
+         dynamic tracing language in that it's based on bytecode,
+         so it doesn't depend upon GCC, doesn't require compiling
+         kernel module for each script, safe to use in production
+         environment, fulfilling the embedded ecosystem's tracing needs.
+
+         See ktap tutorial for more information:
+             http://www.ktap.org/doc/tutorial.html
+
diff --git a/drivers/staging/ktap/Makefile b/drivers/staging/ktap/Makefile
new file mode 100644 (file)
index 0000000..e2e54ba
--- /dev/null
@@ -0,0 +1,101 @@
+
+# Do not instrument the tracer itself:
+ifdef CONFIG_FUNCTION_TRACER
+ORIG_CFLAGS := $(KBUILD_CFLAGS)
+KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS))
+endif
+
+all: mod ktap
+
+INTP = interpreter
+
+LIBDIR = $(INTP)/library
+
+LIB_OBJS += $(LIBDIR)/baselib.o $(LIBDIR)/kdebug.o $(LIBDIR)/timer.o \
+               $(LIBDIR)/ansilib.o
+
+INTP_OBJS += $(INTP)/ktap.o $(INTP)/loader.o $(INTP)/object.o \
+               $(INTP)/tstring.o $(INTP)/table.o $(INTP)/vm.o \
+               $(INTP)/opcode.o $(INTP)/strfmt.o $(INTP)/transport.o \
+               $(LIB_OBJS)
+
+obj-m          += ktapvm.o
+ktapvm-y       := $(INTP_OBJS)
+
+KVERSION ?= $(shell uname -r)
+KERNEL_SRC ?= /lib/modules/$(KVERSION)/build
+mod:
+       $(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules
+
+modules_install:
+       $(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules_install
+
+KTAPC_CFLAGS = -Wall -O2
+
+UDIR = userspace
+
+$(UDIR)/lex.o: $(UDIR)/lex.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/parser.o: $(UDIR)/parser.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/code.o: $(UDIR)/code.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/dump.o: $(UDIR)/dump.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/main.o: $(UDIR)/main.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/util.o: $(UDIR)/util.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/ktapio.o: $(UDIR)/ktapio.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/eventdef.o: $(UDIR)/eventdef.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/opcode.o: $(INTP)/opcode.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/table.o: $(INTP)/table.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/tstring.o: $(INTP)/tstring.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+$(UDIR)/object.o: $(INTP)/object.c
+       $(QUIET_CC)$(CC) $(DEBUGINFO_FLAG) $(KTAPC_CFLAGS) -o $@ -c $<
+
+KTAPOBJS =
+KTAPOBJS += $(UDIR)/lex.o
+KTAPOBJS += $(UDIR)/parser.o
+KTAPOBJS += $(UDIR)/code.o
+KTAPOBJS += $(UDIR)/dump.o
+KTAPOBJS += $(UDIR)/main.o
+KTAPOBJS += $(UDIR)/util.o
+KTAPOBJS += $(UDIR)/ktapio.o
+KTAPOBJS += $(UDIR)/eventdef.o
+KTAPOBJS += $(UDIR)/opcode.o
+KTAPOBJS += $(UDIR)/table.o
+KTAPOBJS += $(UDIR)/tstring.o
+KTAPOBJS += $(UDIR)/object.o
+
+ktap: $(KTAPOBJS)
+       $(QUIET_LINK)$(CC) $(KTAPC_CFLAGS) -o $@ $(KTAPOBJS) -lpthread
+
+KMISC := /lib/modules/$(KVERSION)/ktapvm/
+
+install: mod ktap
+       install -d $(KMISC)
+       install -m 644 -c *.ko /lib/modules/$(KVERSION)/ktapvm/
+       /sbin/depmod -a
+
+load:
+       insmod ktapvm.ko
+
+unload:
+       rmmod ktapvm
+
+test: FORCE
+       cd test; sh ./run_test.sh; cd -
+
+clean:
+       $(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
+       $(RM) ktap
+
+PHONY += FORCE
+FORCE:
+
diff --git a/drivers/staging/ktap/README.md b/drivers/staging/ktap/README.md
new file mode 100644 (file)
index 0000000..c8ddd5f
--- /dev/null
@@ -0,0 +1,144 @@
+# ktap
+
+A New Scripting Dynamic Tracing Tool For Linux  
+[www.ktap.org][homepage]
+
+ktap is a new scripting dynamic tracing tool for Linux,
+it uses a scripting language and lets users trace the Linux kernel dynamically.
+ktap is designed to give operational insights with interoperability
+that allows users to tune, troubleshoot and extend kernel and application.
+It's similar with Linux Systemtap and Solaris Dtrace.
+
+ktap have different design principles from Linux mainstream dynamic tracing
+language in that it's based on bytecode, so it doesn't depend upon GCC,
+doesn't require compiling kernel module for each script, safe to use in
+production environment, fulfilling the embedded ecosystem's tracing needs.
+
+More information can be found at [ktap homepage][homepage].
+
+[homepage]: http://www.ktap.org
+
+## Highlights
+
+  * simple but powerful scripting language
+  * register based interpreter (heavily optimized) in Linux kernel
+  * small and lightweight (6KLOC of interpreter)
+  * not depend on gcc for each script running
+  * easy to use in embedded environment without debugging info
+  * support for tracepoint, kprobe, uprobe, function trace, timer, and more
+  * supported in x86, arm, ppc, mips
+  * safety in sandbox
+
+## Building & Running
+
+1. Clone ktap from github
+
+        $ git clone http://github.com/ktap/ktap.git
+
+2. Compiling ktap
+
+        $ cd ktap
+        $ make       #generate ktapvm kernel module and ktap binary
+
+3. Load ktapvm kernel module(make sure debugfs mounted)
+
+        $ make load  #need to be root or have sudo access
+
+4. Running ktap
+
+        $ ./ktap scripts/helloworld.kp
+
+
+## Examples
+
+1. simplest one-liner command to enable all tracepoints
+
+        ktap -e "trace *:* { print(argevent) }"
+
+2. syscall tracing on target process
+
+        ktap -e "trace syscalls:* { print(argevent) }" -- ls
+
+3. function tracing
+
+        ktap -e "trace ftrace:function { print(argevent) }"
+
+        ktap -e "trace ftrace:function /ip==mutex*/ { print(argevent) }"
+
+4. simple syscall tracing
+
+        trace syscalls:* {
+                print(cpu(), pid(), execname(), argevent)
+        }
+
+5. syscall tracing in histogram style
+
+        s = {}
+
+        trace syscalls:sys_enter_* {
+                s[argname] += 1
+        }
+
+        trace_end {
+                histogram(s)
+        }
+
+6. kprobe tracing
+
+        trace probe:do_sys_open dfd=%di fname=%dx flags=%cx mode=+4($stack) {
+                print("entry:", execname(), argevent)
+        }
+
+        trace probe:do_sys_open%return fd=$retval {
+                print("exit:", execname(), argevent)
+        }
+
+7. uprobe tracing
+
+        trace probe:/lib/libc.so.6:0x000773c0 {
+                print("entry:", execname(), argevent)
+        }
+
+        trace probe:/lib/libc.so.6:0x000773c0%return {
+                print("exit:", execname(), argevent)
+        }
+
+8. timer
+
+        tick-1ms {
+                printf("time fired on one cpu\n");
+        }
+
+        profile-2s {
+                printf("time fired on every cpu\n");
+        }
+
+More sample scripts can be found at scripts/ directory.
+
+## Mailing list
+
+ktap@freelists.org  
+You can subscribe to ktap mailing list at link (subscribe before posting):
+http://www.freelists.org/list/ktap
+
+
+## Copyright and License
+
+ktap is licensed under GPL v2
+
+Copyright (C) 2012-2013, Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+All rights reserved.  
+
+
+## Contribution
+
+ktap is still under active development, so contributions are welcome.
+You are encouraged to report bugs, provide feedback, send feature request,
+or hack on it.
+
+
+## See More
+
+More info can be found at [documentation][tutorial]
+[tutorial]: http://www.ktap.org/doc/tutorial.html
+
diff --git a/drivers/staging/ktap/doc/tutorial.md b/drivers/staging/ktap/doc/tutorial.md
new file mode 100644 (file)
index 0000000..3c32ce7
--- /dev/null
@@ -0,0 +1,552 @@
+% The ktap Tutorial
+
+# Introduction
+
+ktap is a new scripting dynamic tracing tool for linux
+
+ktap is a new scripting dynamic tracing tool for Linux,
+it uses a scripting language and lets users trace the Linux kernel dynamically.
+ktap is designed to give operational insights with interoperability
+that allows users to tune, troubleshoot and extend kernel and application.
+It's similar with Linux Systemtap and Solaris Dtrace.
+
+ktap have different design principles from Linux mainstream dynamic tracing
+language in that it's based on bytecode, so it doesn't depend upon GCC,
+doesn't require compiling kernel module for each script, safe to use in
+production environment, fulfilling the embedded ecosystem's tracing needs.
+
+Highlights features:
+
+* simple but powerful scripting language
+* register based interpreter (heavily optimized) in Linux kernel
+* small and lightweight (6KLOC of interpreter)
+* not depend on gcc for each script running
+* easy to use in embedded environment without debugging info
+* support for tracepoint, kprobe, uprobe, function trace, timer, and more
+* supported in x86, arm, ppc, mips
+* safety in sandbox
+
+
+# Getting started
+
+Requirements
+
+* Linux 3.1 or later(Need some kernel patches for kernel earlier than 3.1)
+* CONFIG_EVENT_TRACING enabled
+* CONFIG_PERF_EVENTS enabled
+* CONFIG_DEBUG_FS enabled  
+  (make sure debugfs mounted before insmod ktapvm  
+   mount debugfs: mount -t debugfs none /sys/kernel/debug/)
+
+Note that those configuration is always enabled in Linux distribution,
+like REHL, Fedora, Ubuntu, etc.
+
+1. Clone ktap from github
+
+        $ git clone http://github.com/ktap/ktap.git
+
+2. Compiling ktap
+
+        $ cd ktap
+        $ make       #generate ktapvm kernel module and ktap binary
+
+3. Load ktapvm kernel module(make sure debugfs mounted)
+
+        $ make load  #need to be root or have sudo access
+
+4. Running ktap
+
+        $ ./ktap scripts/helloworld.kp
+
+
+# Language basics
+
+## Syntax basics
+
+ktap's syntax is design on the mind of C language syntax friendly,
+to make it easy scripting by kernel developer.
+
+1. Variable declaration
+The biggest syntax differences with C is that ktap is a dynamic typed
+language, so you won't need add any variable type declaration, just
+use the variable.
+
+2. function
+All functions in ktap should use keyword "function" declaration
+
+3. comments
+The comments of ktap is starting from '#', long comments doesn't support now.
+
+4. others
+Don't need place any ';' at the ending of statement in ktap.
+ktap use free syntax style, so you can choose to use the ';' or not.
+
+ktap use nil as NULL, the result of any number operate on nil is nil.
+
+ktap don't have array structure, also don't have any pointer operation.
+
+## Control structures
+
+ktap if/else is same as C language.
+
+There have two method of for-loop in ktap:
+
+    for (i = init, limit, step) { body }
+
+this is same as below in C:
+
+    for (i = init; i < limit; i += step) { body }
+
+The next for-loop method is:
+
+    for (k, v in pairs(t)) { body }   # looping all elements of table
+
+Note that ktap don't have "continue" keyword, but C does.
+
+## Date structures
+
+Associative array is heavily used in ktap, it's also called by table.
+
+table declaration:
+
+    t = {}
+
+how to use table:  
+
+    t[1] = 1
+    t[1] = "xxx"
+    t["key"] = 10
+    t["key"] = "value"
+
+    for (k, v in pairs(t)) { body }   # looping all elements of table
+
+
+# Built in functions and librarys
+
+## Built in functions
+
+**print (...)**  
+Receives any number of arguments, and prints their values,
+print is not intended for formatted output, but only as a
+quick way to show a value, typically for debugging.
+For formatted output, use printf.
+
+**printf (fmt, ...)**  
+Similar with C printf, use for format string output.
+
+**pairs (t)**  
+Returns three values: the next function, the table t, and nil,
+so that the construction
+for (k,v in pairs(t)) { body }
+will iterate over all key-value pairs of table t.
+
+**len (t) /len (s)**  
+If the argument is string, return length of string,
+if the argument is table, return counts of table pairs.
+
+**in_interrupt ()**  
+checking is context is interrupt context
+  
+**exit ()**  
+quit ktap executing, similar with exit syscall
+
+**pid ()**  
+return current process pid
+
+**execname ()**  
+return current process exec name string
+
+**cpu ()**  
+return current cpu id
+
+**arch ()**  
+return machine architecture, like x86, arm, etc.
+
+**kernel_v ()**  
+return Linux kernel version string, like 3.9, etc.
+
+**user_string (addr)**  
+Receive userspace address, read string from userspace, return string.
+
+**histogram (t)**  
+Receive table, output table histogram to user.
+
+**curr_task_info (offset, fetch_bytes)**  
+fetch value in field offset of task_struct structure, argument fetch_bytes
+could be 4 or 8, if fetch_bytes is not given, default is 4.
+
+user may need to get field offset by gdb, for example:
+gdb vmlinux
+(gdb)p &(((struct task_struct *)0).prio)
+
+**print_backtrace ()**  
+print current task stack info
+
+
+## Librarys
+
+### Kdebug Library
+
+**kdebug.probe_by_id (event_ids, eventfun)**
+
+This function is underly representation of high level tracing primitive.
+event_ids is the id of all events, it's read from  
+/sys/kernel/debug/tracing/events/$SYS/$EVENT/id
+
+for multi-events tracing, the event_ids is concatenation of all id, for example:
+ "2 3 4", seperated by blank space.
+
+The second argument in above examples is a function:  
+function eventfun () { action }
+
+
+**kdebug.probe_end (endfunc)**  
+
+This function is used for invoking a function when tracing end, it will wait
+until user press CTRL+C to stop tracing, then ktap will call endfunc function, 
+user could show tracing results in that function, or do other things.
+
+
+### Timer Library
+
+
+
+# Linux tracing basics
+
+tracepoints, probe, timer  
+filters  
+above explaintion  
+Ring buffer
+
+# Tracing semantics in ktap
+
+## Tracing block
+
+**trace EVENTDEF /FILTER/ { ACTION }**
+
+This is the basic tracing block for ktap, you need to use a specific EVENTDEF
+string, and own event function.
+
+EVENTDEF is compatible with perf(see perf-list), with glob match, for example:
+
+       syscalls:*                      trace all syscalls events
+       syscalls:sys_enter_*            trace all syscalls entry events
+       kmem:*                          trace all kmem related events
+       sched:*                         trace all sched related events
+       *:*                             trace all tracepoints in system.
+
+All events are based on: /sys/kernel/debug/tracing/events/$SYS/$EVENT
+
+**trace_end { ACTION }**
+
+This is based on kdebug.probe_end function.
+
+## Tracing built-in variable  
+
+**argevent**  
+event object, you can print it by: print(argevent), it will print events
+into human readable string, the result is mostly same as each entry of
+/sys/kernel/debug/tracing/trace
+
+**argname**  
+event name, each event have a name associated with it.
+
+**arg1..9**  
+get argument 1..9 of event object.
+
+
+## Timer syntax
+
+**tick-Ns        { ACTION }**  
+**tick-Nsec      { ACTION }**  
+**tick-Nms       { ACTION }**  
+**tick-Nmsec     { ACTION }**  
+**tick-Nus       { ACTION }**  
+**tick-Nusec     { ACTION }**
+
+**profile-Ns     { ACTION }**  
+**profile-Nsec   { ACTION }**  
+**profile-Nms    { ACTION }**  
+**profile-Nmsec  { ACTION }**  
+**profile-Nus    { ACTION }**  
+**profile-Nusec  { ACTION }**  
+
+architecture overview picture reference(pnp format)  
+one-liners  
+simple event tracing
+
+# Advanced tracing pattern
+
+Aggregation/Histogram  
+thread local  
+flame graph
+
+# Overhead/Performance
+
+ktap have more fast boot time thant Systemtap(try the helloword script)  
+ktap have little memory usage than Systemtap  
+and some scripts show that ktap have a little overhead then Systemtap
+(we choosed two scripts to compare, function profile, stack profile.
+this is not means all scripts in Systemtap have big overhead than ktap)
+
+
+# FAQ
+
+**Q: Why use bytecode design?**  
+A: Using bytecode would be a clean and lightweight solution,
+   you don't need gcc toolchain to compile every scripts, all you
+   need is a ktapvm kernel modules and userspace tool called ktap.
+   Since its language virtual machine design, it have great portability,
+   suppose you are working at a multi-arch cluster, if you want to run
+   a tracing script on each board, you won't need cross-compile tracing
+   script onto all board, what you really need to do is use ktap tool
+   to run script just in time.
+
+   Bytecode based design also will make executing more safer, than native code
+   generation.
+
+   Reality already showing that SystemTap is not widely used in embedded Linux,
+   caused by problem of SystemTap's architecture design choice, it's a natural
+   design for Redhat and IBM, because Redhat/IBM is focusing on server area,
+   not embedded area.
+
+**Q: What's the differences with SystemTap and Dtrace?**  
+A: For SystemTap, the answer is already mentioned at above question,
+   SystemTap use translator design, for trade-off on performance with usability,
+   based on GCC, that's what ktap want to solve.
+
+   For Dtrace, one common design with Dtrace is also use bytecode, so basically
+   Dtrace and ktap is on the same road. There have some projects aim to porting
+   Dtrace from Solaris to Linux, but the process is still on the road, Dtrace
+   is rooted in Solaris, and there have many huge differences between Solaris
+   tracing infrastructure with Linux's.
+
+   Dtrace is based on D language, a language subset of C, it's a restricted
+   language, like without for-looping, for safty use in production system.
+   It seems that Dtrace for Linux only support x86 architecture, not work on
+   powerpc and arm/mips, obviously it's not suit for embedded Linux currently.
+
+   Dtrace use ctf as input for debuginfo handing, compare with vmlinux for
+   SystemTap.
+
+   On the license part, Dtrace is released as CDDL, which is incompatible with
+   GPL(this is why it's impossible to upstream Dtrace into mainline).
+
+**Q: Why use dynamically typed language? but not statically typed language?**  
+A: It's hard to say which one is more better than other, dynamically typed
+   language bring efficiency and fast prototype production, but loosing type
+   check at compiling phase, and easy to make mistake in runtime, also it's
+   need many runtime checking, In contrast, statically typed language win on
+   programing safety, and performance. Statically language would suit for
+   interoperate with kernel, as kernel is wrote mainly in C, Need to note that
+   SystemTap and Dtrace both is statically language.
+
+   ktap choose dynamically typed language as initial implementation.
+
+**Q: Why we need ktap for event tracing? There already have a built-in ftrace**  
+A: This also is a common question for all dynamic tracing tool, not only ktap.
+   ktap provide more flexibility than built-in tracing infrastructure. Suppose
+   you need print a global variable when tracepoint hit, or you want print
+   backtrace, even more, you want to store some info into associative array, and
+   display it in histogram style when tracing end, in these case, some of them
+   ftrace can take it, some of them ftrace can not.
+   Overall, ktap provide you with great flexibility to scripting your own trace
+   need.
+
+**Q: How about the performance? Is ktap slow?**  
+A: ktap is not slow, the bytecode is very high-level, based on lua, the language
+   virtual machine is register-based(compare with stack-based), with little
+   instruction, the table data structure is heavily optimized in ktapvm.
+   ktap use per-cpu allocation in many place, without global locking scheme,
+   it's very fast when executing tracepoint callback.
+   Performance benchmark showing that the overhead of ktap running is nearly
+   10%(store event name into associative array), compare with full speed
+   running without any tracepoint enabled.
+
+   ktap will optimize overhead all the time, hopefully the overhead will
+   decrease to little than 5%, even more.
+
+**Q: Why not porting a high level language implementation into kernel directly?
+   Like python/JVM?**  
+A: I take serious on the size of vm and memory footprint. Python vm is large,
+   it's not suit to embed into kernel, and python have some functionality
+   which we don't need.
+
+   The bytecode of other high level language is also big, ktap only have 32
+   bytecodes, python/java/erlang have nearly two hundred bytecodes.
+   There also have some problems when porting those language into kernel,
+   userspace programming have many differences with kernel programming,
+   like float numbers, handle sleeping code carefully in kernel, deadloop is
+   not allowed in kernel, multi-thread management, etc.., so it's impossible
+   to porting language implementation into kernel with little adaption work.
+
+**Q: What's the status of ktap now?**  
+A: Basically it works on x86-32, x86-64, powerpc, arm, it also could work for
+   other hardware architecture, but not proven yet(I don't have enough hardware
+   to test)
+   If you found some bug, fix it on you own programming skill, or report to me.
+
+**Q: How to hack ktap? I want to write some extensions onto ktap.**  
+A: welcome hacking.  
+   You can write your own library to fulfill your specific need,
+   you can write any script as you want.
+
+**Q: What's the plan of ktap? any roadmap?**  
+A: the current plan is deliver stable ktapvm kernel modules, more ktap script,
+   and bugfix.
+
+
+# References
+
+* [Linux Performance Analysis and Tools][LPAT]
+* [Dtrace Blog][dtraceblog]
+* [Dtrace User Guide][dug]
+* [LWN: ktap -- yet another kernel tracer][lwn]
+* [ktap introduction in LinuxCon Japan 2013][lcj]
+
+[LPAT]: http://www.brendangregg.com/Slides/SCaLE_Linux_Performance2013.pdf
+[dtraceblog]: http://dtrace.org/blogs/
+[dug]: http://docs.huihoo.com/opensolaris/dtrace-user-guide/html/index.html
+[lwn]: http://lwn.net/Articles/551314/
+[lcj]: http://events.linuxfoundation.org/sites/events/files/lcjpcojp13_zhangwei.pdf
+
+
+# History
+
+* ktap was invented at 2002
+* First RFC sent to LKML at 2012.12.31
+* The code was released in github at 2013.01.18
+* ktap released v0.1 at 2013.05.21
+* ktap released v0.2 at 2013.07.31
+
+For more release info, please look at RELEASES.txt in project root directory.
+
+# Sample scripts
+
+1. simplest one-liner command to enable all tracepoints
+
+        ktap -e "trace *:* { print(argevent) }"
+
+2. syscall tracing on target process
+
+        ktap -e "trace syscalls:* { print(argevent) }" -- ls
+
+3. function tracing
+
+        ktap -e "trace ftrace:function { print(argevent) }"
+
+        ktap -e "trace ftrace:function /ip==mutex*/ { print(argevent) }"
+
+4. simple syscall tracing
+
+        trace syscalls:* {
+                print(cpu(), pid(), execname(), argevent)
+        }
+
+5. syscall tracing in histogram style
+
+        s = {}
+
+        trace syscalls:sys_enter_* {
+                s[argname] += 1
+        }
+
+        trace_end {
+                histogram(s)
+        }
+
+6. kprobe tracing
+
+        trace probe:do_sys_open dfd=%di fname=%dx flags=%cx mode=+4($stack) {
+                print("entry:", execname(), argevent)
+        }
+
+        trace probe:do_sys_open%return fd=$retval {
+                print("exit:", execname(), argevent)
+        }
+
+7. uprobe tracing
+
+        trace probe:/lib/libc.so.6:0x000773c0 {
+                print("entry:", execname(), argevent)
+        }
+
+        trace probe:/lib/libc.so.6:0x000773c0%return {
+                print("exit:", execname(), argevent)
+        }
+
+8. timer
+
+        tick-1ms {
+                printf("time fired on one cpu\n");
+        }
+
+        profile-2s {
+                printf("time fired on every cpu\n");
+        }
+
+More sample scripts can be found at scripts/ directory.
+
+
+# Appendix
+
+Here is the complete syntax of ktap in extended BNF.
+(based on lua syntax: http://www.lua.org/manual/5.1/manual.html#5.1)
+
+        chunk ::= {stat [';']} [laststat [';']
+
+        block ::= chunk
+
+        stat ::=  varlist '=' explist | 
+                 functioncall | 
+                 { block } | 
+                 while exp { block } | 
+                 repeat block until exp | 
+                 if exp { block {elseif exp { block }} [else block] } | 
+                 for Name '=' exp ',' exp [',' exp] { block } | 
+                 for namelist in explist { block } | 
+                 function funcname funcbody | 
+                 local function Name funcbody | 
+                 local namelist ['=' explist] 
+
+        laststat ::= return [explist] | break
+
+        funcname ::= Name {'.' Name} [':' Name]
+
+        varlist ::= var {',' var}
+
+        var ::=  Name | prefixexp '[' exp ']'| prefixexp '.' Name 
+
+        namelist ::= Name {',' Name}
+
+        explist ::= {exp ',' exp
+
+        exp ::=  nil | false | true | Number | String | '...' | function | 
+                 prefixexp | tableconstructor | exp binop exp | unop exp 
+
+        prefixexp ::= var | functioncall | '(' exp ')'
+
+        functioncall ::=  prefixexp args | prefixexp ':' Name args 
+
+        args ::=  '(' [explist] ')' | tableconstructor | String 
+
+        function ::= function funcbody
+
+        funcbody ::= '(' [parlist] ')' { block }
+
+        parlist ::= namelist [',' '...'] | '...'
+
+        tableconstructor ::= '{' [fieldlist] '}'
+
+        fieldlist ::= field {fieldsep field} [fieldsep]
+
+        field ::= '[' exp ']' '=' exp | Name '=' exp | exp
+
+        fieldsep ::= ',' | ';'
+
+        binop ::= '+' | '-' | '*' | '/' | '^' | '%' | '..' | 
+                  '<' | '<=' | '>' | '>=' | '==' | '!=' | 
+                  and | or
+
+        unop ::= '-'
+
diff --git a/drivers/staging/ktap/include/ktap.h b/drivers/staging/ktap/include/ktap.h
new file mode 100644 (file)
index 0000000..076dd4a
--- /dev/null
@@ -0,0 +1,169 @@
+#ifndef __KTAP_H__
+#define __KTAP_H__
+
+#include "ktap_types.h"
+#include "ktap_opcodes.h"
+
+#include <linux/version.h>
+#include <linux/hardirq.h>
+#include <linux/perf_event.h>
+#include <linux/trace_seq.h>
+
+typedef struct ktap_Reg {
+        const char *name;
+        ktap_cfunction func;
+} ktap_Reg;
+
+struct ktap_probe_event {
+       struct list_head list;
+       struct perf_event *perf;
+       ktap_state *ks;
+       ktap_closure *cl;
+};
+
+/* this structure allocate on stack */
+struct ktap_event {
+       struct ktap_probe_event *pevent;
+       struct ftrace_event_call *call;
+       struct trace_entry *entry;
+       int entry_size;
+       struct pt_regs *regs;
+};
+
+enum {
+       KTAP_PERCPU_DATA_STATE,
+       KTAP_PERCPU_DATA_STACK,
+       KTAP_PERCPU_DATA_BUFFER,
+       KTAP_PERCPU_DATA_BUFFER2,
+       KTAP_PERCPU_DATA_BTRACE,
+
+       KTAP_PERCPU_DATA_MAX
+};
+
+#define KTAP_PERCPU_BUFFER_SIZE        (3 * PAGE_SIZE)
+
+int gettimeofday_us(void);
+ktap_state *kp_newstate(struct ktap_parm *parm, struct dentry *dir);
+void kp_exit(ktap_state *ks);
+void kp_final_exit(ktap_state *ks);
+ktap_state *kp_newthread(ktap_state *mainthread);
+void kp_exitthread(ktap_state *ks);
+ktap_closure *kp_load(ktap_state *ks, unsigned char *buff);
+void kp_call(ktap_state *ks, StkId func, int nresults);
+void kp_optimize_code(ktap_state *ks, int level, ktap_proto *f);
+void kp_register_lib(ktap_state *ks, const char *libname, const ktap_Reg *funcs);
+void *kp_percpu_data(int type);
+
+void kp_init_baselib(ktap_state *ks);
+void kp_init_oslib(ktap_state *ks);
+void kp_init_kdebuglib(ktap_state *ks);
+void kp_init_timerlib(ktap_state *ks);
+void kp_init_ansilib(ktap_state *ks);
+
+int kp_probe_init(ktap_state *ks);
+void kp_probe_exit(ktap_state *ks);
+
+void kp_perf_event_register(ktap_state *ks, struct perf_event_attr *attr,
+                           struct task_struct *task, char *filter,
+                           ktap_closure *cl);
+
+void kp_event_getarg(ktap_state *ks, ktap_value *ra, int n);
+void kp_event_tostring(ktap_state *ks, struct trace_seq *seq);
+
+int kp_strfmt(ktap_state *ks, struct trace_seq *seq);
+
+void kp_transport_write(ktap_state *ks, const void *data, size_t length);
+void kp_transport_event_write(ktap_state *ks, struct ktap_event *e);
+void kp_transport_print_backtrace(ktap_state *ks);
+void *kp_transport_reserve(ktap_state *ks, size_t length);
+void kp_transport_exit(ktap_state *ks);
+int kp_transport_init(ktap_state *ks, struct dentry *dir);
+
+void kp_exit_timers(ktap_state *ks);
+
+extern int kp_max_exec_count;
+
+/* get from kernel/trace/trace.h */
+static __always_inline int trace_get_context_bit(void)
+{
+       int bit;
+
+       if (in_interrupt()) {
+               if (in_nmi())
+                       bit = 0;
+               else if (in_irq())
+                       bit = 1;
+               else
+                       bit = 2;
+       } else
+               bit = 3;
+
+       return bit;
+}
+
+/* use a special timer context kp_state instead use this recursion approach? */
+DECLARE_PER_CPU(int, kp_recursion_context[PERF_NR_CONTEXTS]);
+
+static __always_inline int get_recursion_context(void)
+{
+       int rctx = trace_get_context_bit();
+
+       if (__this_cpu_read(kp_recursion_context[rctx]))
+               return -1;
+
+       __this_cpu_write(kp_recursion_context[rctx], true);
+       barrier();
+
+       return rctx;
+}
+
+static inline void put_recursion_context(int rctx)
+{
+       barrier();
+       __this_cpu_write(kp_recursion_context[rctx], false);
+}
+
+
+extern unsigned int kp_stub_exit_instr;
+
+static inline void set_next_as_exit(ktap_state *ks)
+{
+       ktap_callinfo *ci;
+
+       ci = ks->ci;
+       if (!ci)
+               return;
+
+       ci->u.l.savedpc = &kp_stub_exit_instr;
+
+       /* See precall, ci changed to ci->prev after invoke C function */
+       if (ci->prev) {
+               ci = ci->prev;
+               ci->u.l.savedpc = &kp_stub_exit_instr;
+       }
+}
+
+#define kp_verbose_printf(ks, ...) \
+       if (G(ks)->parm->verbose)       \
+               kp_printf(ks, "[verbose] "__VA_ARGS__);
+
+/* get argument operation macro */
+#define kp_arg(ks, n)  ((ks)->ci->func + (n))
+#define kp_arg_nr(ks)  ((int)(ks->top - (ks->ci->func + 1)))
+
+#define kp_arg_check(ks, narg, type)                           \
+       do {                                                    \
+               if (unlikely(ttypenv(kp_arg(ks, narg)) != type)) {      \
+                       kp_error(ks, "wrong type of argument %d\n", narg);\
+                       return -1;                              \
+               }                                               \
+       } while (0)
+
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 5, 0)
+#define SPRINT_SYMBOL  sprint_symbol_no_offset
+#else
+#define SPRINT_SYMBOL  sprint_symbol
+#endif
+
+#endif /* __KTAP_H__ */
diff --git a/drivers/staging/ktap/include/ktap_opcodes.h b/drivers/staging/ktap/include/ktap_opcodes.h
new file mode 100644 (file)
index 0000000..31c558b
--- /dev/null
@@ -0,0 +1,240 @@
+#ifndef __KTAP_BYTECODE_H__
+#define __KTAP_BYTECODE_H__
+
+
+/* opcode is copied from lua initially */
+typedef enum {
+/*----------------------------------------------------------------------
+ * name            args    description
+ * ------------------------------------------------------------------------*/
+OP_MOVE,/*      A B     R(A) := R(B)                                    */
+OP_LOADK,/*     A Bx    R(A) := Kst(Bx)                                 */
+OP_LOADKX,/*    A       R(A) := Kst(extra arg)                          */
+OP_LOADBOOL,/*  A B C   R(A) := (Bool)B; if (C) pc++                    */
+OP_LOADNIL,/*   A B     R(A), R(A+1), ..., R(A+B) := nil                */
+OP_GETUPVAL,/*  A B     R(A) := UpValue[B]                              */
+
+OP_GETTABUP,/*  A B C   R(A) := UpValue[B][RK(C)]                       */
+OP_GETTABLE,/*  A B C   R(A) := R(B)[RK(C)]                             */
+
+OP_SETTABUP,/*  A B C   UpValue[A][RK(B)] := RK(C)                      */
+OP_SETTABUP_INCR,/*  A B C   UpValue[A][RK(B)] += RK(C)                 */
+OP_SETUPVAL,/*  A B     UpValue[B] := R(A)                              */
+OP_SETTABLE,/*  A B C   R(A)[RK(B)] := RK(C)                            */
+OP_SETTABLE_INCR,/*  A B C   R(A)[RK(B)] += RK(C)                       */
+
+OP_NEWTABLE,/*  A B C   R(A) := {} (size = B,C)                         */
+
+OP_SELF,/*      A B C   R(A+1) := R(B); R(A) := R(B)[RK(C)]             */
+
+OP_ADD,/*       A B C   R(A) := RK(B) + RK(C)                           */
+OP_SUB,/*       A B C   R(A) := RK(B) - RK(C)                           */
+OP_MUL,/*       A B C   R(A) := RK(B) * RK(C)                           */
+OP_DIV,/*       A B C   R(A) := RK(B) / RK(C)                           */
+OP_MOD,/*       A B C   R(A) := RK(B) % RK(C)                           */
+OP_POW,/*       A B C   R(A) := RK(B) ^ RK(C)                           */
+OP_UNM,/*       A B     R(A) := -R(B)                                   */
+OP_NOT,/*       A B     R(A) := not R(B)                                */
+OP_LEN,/*       A B     R(A) := length of R(B)                          */
+
+OP_CONCAT,/*    A B C   R(A) := R(B).. ... ..R(C)                       */
+
+OP_JMP,/*       A sBx   pc+=sBx; if (A) close all upvalues >= R(A) + 1  */
+OP_EQ,/*        A B C   if ((RK(B) == RK(C)) != A) then pc++            */
+OP_LT,/*        A B C   if ((RK(B) <  RK(C)) != A) then pc++            */
+OP_LE,/*        A B C   if ((RK(B) <= RK(C)) != A) then pc++            */
+
+OP_TEST,/*      A C     if not (R(A) <=> C) then pc++                   */
+OP_TESTSET,/*   A B C   if (R(B) <=> C) then R(A) := R(B) else pc++     */
+
+OP_CALL,/*      A B C   R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
+OP_TAILCALL,/*  A B C   return R(A)(R(A+1), ... ,R(A+B-1))              */
+OP_RETURN,/*    A B     return R(A), ... ,R(A+B-2)      (see note)      */
+
+OP_FORLOOP,/*   A sBx   R(A)+=R(A+2);
+                        if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
+OP_FORPREP,/*   A sBx   R(A)-=R(A+2); pc+=sBx                           */
+
+OP_TFORCALL,/*  A C     R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));  */
+OP_TFORLOOP,/*  A sBx   if R(A+1) != nil then { R(A)=R(A+1); pc += sBx }*/
+
+OP_SETLIST,/*   A B C   R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B        */
+
+OP_CLOSURE,/*   A Bx    R(A) := closure(KPROTO[Bx])                     */
+
+OP_VARARG,/*    A B     R(A), R(A+1), ..., R(A+B-2) = vararg            */
+
+OP_EXTRAARG,/*   Ax      extra (larger) argument for previous opcode     */
+
+OP_EVENT,/*  A B C   R(A) := R(B)[C]                             */
+
+OP_EVENTNAME, /* A     R(A) = event_name() */
+
+OP_EVENTARG,/* A B     R(A) := event_arg(B)*/
+
+OP_LOAD_GLOBAL,/*  A B C   R(A) := R(B)[C]                             */
+
+OP_EXIT,
+
+} OpCode;
+
+
+#define NUM_OPCODES     ((int)OP_LOAD_GLOBAL + 1)
+
+
+enum OpMode {iABC, iABx, iAsBx, iAx};  /* basic instruction format */
+
+
+/*
+ * ** size and position of opcode arguments.
+ * */
+#define SIZE_C          9
+#define SIZE_B          9
+#define SIZE_Bx         (SIZE_C + SIZE_B)
+#define SIZE_A          8
+#define SIZE_Ax         (SIZE_C + SIZE_B + SIZE_A)
+
+#define SIZE_OP         6
+
+#define POS_OP          0
+#define POS_A           (POS_OP + SIZE_OP)
+#define POS_C           (POS_A + SIZE_A)
+#define POS_B           (POS_C + SIZE_C)
+#define POS_Bx          POS_C
+#define POS_Ax          POS_A
+
+
+
+/*
+ * ** limits for opcode arguments.
+ * ** we use (signed) int to manipulate most arguments,
+ * ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
+ * */
+#define MAXARG_Bx        ((1<<SIZE_Bx)-1)
+#define MAXARG_sBx        (MAXARG_Bx>>1)         /* `sBx' is signed */
+
+#define MAXARG_Ax       ((1<<SIZE_Ax)-1)
+
+#define MAXARG_A        ((1<<SIZE_A)-1)
+#define MAXARG_B        ((1<<SIZE_B)-1)
+#define MAXARG_C        ((1<<SIZE_C)-1)
+
+
+/* creates a mask with `n' 1 bits at position `p' */
+#define MASK1(n,p)      ((~((~(ktap_instruction)0)<<(n)))<<(p))
+
+/* creates a mask with `n' 0 bits at position `p' */
+#define MASK0(n,p)      (~MASK1(n,p))
+
+/*
+ * ** the following macros help to manipulate instructions
+ * */
+
+#define GET_OPCODE(i)   ((OpCode)((i)>>POS_OP) & MASK1(SIZE_OP,0))
+#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
+                ((((ktap_instruction)o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
+
+#define getarg(i,pos,size)      ((int)((i)>>pos) & MASK1(size,0))
+#define setarg(i,v,pos,size)    ((i) = (((i)&MASK0(size,pos)) | \
+                ((((ktap_instruction)v)<<pos)&MASK1(size,pos))))
+
+#define GETARG_A(i)     getarg(i, POS_A, SIZE_A)
+#define SETARG_A(i,v)   setarg(i, v, POS_A, SIZE_A)
+
+#define GETARG_A(i)     getarg(i, POS_A, SIZE_A)
+#define SETARG_A(i,v)   setarg(i, v, POS_A, SIZE_A)
+
+#define GETARG_B(i)     getarg(i, POS_B, SIZE_B)
+#define SETARG_B(i,v)   setarg(i, v, POS_B, SIZE_B)
+
+#define GETARG_C(i)     getarg(i, POS_C, SIZE_C)
+#define SETARG_C(i,v)   setarg(i, v, POS_C, SIZE_C)
+
+#define GETARG_Bx(i)    getarg(i, POS_Bx, SIZE_Bx)
+#define SETARG_Bx(i,v)  setarg(i, v, POS_Bx, SIZE_Bx)
+
+#define GETARG_Ax(i)    getarg(i, POS_Ax, SIZE_Ax)
+#define SETARG_Ax(i,v)  setarg(i, v, POS_Ax, SIZE_Ax)
+
+#define GETARG_sBx(i)   (GETARG_Bx(i)-MAXARG_sBx)
+#define SETARG_sBx(i,b) SETARG_Bx((i), (unsigned int)(b)+MAXARG_sBx)
+
+#define CREATE_ABC(o,a,b,c)     (((ktap_instruction)(o))<<POS_OP) \
+                        | (((ktap_instruction)(a))<<POS_A) \
+                        | (((ktap_instruction)(b))<<POS_B) \
+                        | (((ktap_instruction)(c))<<POS_C)
+
+#define CREATE_ABx(o,a,bc)      (((ktap_instruction)(o))<<POS_OP) \
+                        | (((ktap_instruction)(a))<<POS_A) \
+                        | (((ktap_instruction)(bc))<<POS_Bx)
+
+#define CREATE_Ax(o,a)          (((ktap_instruction)(o))<<POS_OP) \
+                        | (((ktap_instruction)(a))<<POS_Ax)
+
+
+
+/*
+ * ** Macros to operate RK indices
+ * */
+
+/* this bit 1 means constant (0 means register) */
+#define BITRK           (1 << (SIZE_B - 1))
+
+/* test whether value is a constant */
+#define ISK(x)          ((x) & BITRK)
+
+/* gets the index of the constant */
+#define INDEXK(r)       ((int)(r) & ~BITRK)
+
+#define MAXINDEXRK      (BITRK - 1)
+
+/* code a constant index as a RK value */
+#define RKASK(x)        ((x) | BITRK)
+
+
+/*
+ * ** invalid register that fits in 8 bits
+ * */
+#define NO_REG          MAXARG_A
+
+
+/*
+ * ** R(x) - register
+ * ** Kst(x) - constant (in constant table)
+ * ** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
+ * */
+
+
+
+/*
+ * ** masks for instruction properties. The format is:
+ * ** bits 0-1: op mode
+ * ** bits 2-3: C arg mode
+ * ** bits 4-5: B arg mode
+ * ** bit 6: instruction set register A
+ * ** bit 7: operator is a test (next instruction must be a jump)
+ * */
+
+enum OpArgMask {
+  OpArgN,  /* argument is not used */
+  OpArgU,  /* argument is used */
+  OpArgR,  /* argument is a register or a jump offset */
+  OpArgK   /* argument is a constant or register/constant */
+};
+
+extern const u8 ktap_opmodes[NUM_OPCODES];
+
+#define getOpMode(m)    ((enum OpMode)ktap_opmodes[m] & 3)
+#define getBMode(m)     ((enum OpArgMask)(ktap_opmodes[m] >> 4) & 3)
+#define getCMode(m)     ((enum OpArgMask)(ktap_opmodes[m] >> 2) & 3)
+#define testAMode(m)    (ktap_opmodes[m] & (1 << 6))
+#define testTMode(m)    (ktap_opmodes[m] & (1 << 7))
+
+
+/* number of list items to accumulate before a SETLIST instruction */
+#define LFIELDS_PER_FLUSH       50
+
+extern const char *const ktap_opnames[NUM_OPCODES + 1];
+
+#endif /* __KTAP_BYTECODE_H__ */
diff --git a/drivers/staging/ktap/include/ktap_types.h b/drivers/staging/ktap/include/ktap_types.h
new file mode 100644 (file)
index 0000000..cf1cef4
--- /dev/null
@@ -0,0 +1,674 @@
+#ifndef __KTAP_TYPES_H__
+#define __KTAP_TYPES_H__
+
+/* opcode is copied from lua initially */
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/semaphore.h>
+#include <linux/wait.h>
+#else
+typedef char u8;
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#endif
+
+typedef struct ktap_parm {
+       char *trunk; /* __user */
+       int trunk_len;
+       int argc;
+       char **argv; /* __user */
+       int verbose;
+       int trace_pid;
+       int workload;
+       int trace_cpu;
+       int print_timestamp;
+} ktap_parm;
+
+/*
+ * Ioctls that can be done on a ktap fd:
+ * todo: use _IO macro in include/uapi/asm-generic/ioctl.h
+ */
+#define KTAP_CMD_IOC_VERSION           ('$' + 0)
+#define KTAP_CMD_IOC_RUN               ('$' + 1)
+#define KTAP_CMD_IOC_EXIT              ('$' + 3)
+
+#define KTAP_ENV       "_ENV"
+
+#define KTAP_VERSION_MAJOR       "0"
+#define KTAP_VERSION_MINOR       "2"
+
+#define KTAP_VERSION    "ktap " KTAP_VERSION_MAJOR "." KTAP_VERSION_MINOR
+#define KTAP_AUTHOR    "Jovi Zhangwei <jovi.zhangwei@gmail.com>"
+#define KTAP_COPYRIGHT  KTAP_VERSION "  Copyright (C) 2012-2013, " KTAP_AUTHOR
+
+#define MYINT(s)        (s[0] - '0')
+#define VERSION         (MYINT(KTAP_VERSION_MAJOR) * 16 + MYINT(KTAP_VERSION_MINOR))
+#define FORMAT          0 /* this is the official format */
+
+#define KTAP_SIGNATURE  "\033ktap"
+
+/* data to catch conversion errors */
+#define KTAPC_TAIL      "\x19\x93\r\n\x1a\n"
+
+/* size in bytes of header of binary files */
+#define KTAPC_HEADERSIZE       (sizeof(KTAP_SIGNATURE) - sizeof(char) + 2 + \
+                                6 + sizeof(KTAPC_TAIL) - sizeof(char))
+
+typedef int ktap_instruction;
+
+typedef union ktap_gcobject ktap_gcobject;
+
+#define CommonHeader ktap_gcobject *next; u8 tt;
+
+struct ktap_state;
+typedef int (*ktap_cfunction) (struct ktap_state *ks);
+
+typedef union ktap_string {
+       int dummy;  /* ensures maximum alignment for strings */
+       struct {
+               CommonHeader;
+               u8 extra;  /* reserved words for short strings; "has hash" for longs */
+               unsigned int hash;
+               size_t len;  /* number of characters in string */
+       } tsv;
+} ktap_string;
+
+#define getstr(ts)     (const char *)((ts) + 1)
+#define eqshrstr(a,b)  ((a) == (b))
+
+#define svalue(o)       getstr(rawtsvalue(o))
+
+
+union _ktap_value {
+       ktap_gcobject *gc;    /* collectable objects */
+       void *p;         /* light userdata */
+       int b;           /* booleans */
+       ktap_cfunction f; /* light C functions */
+       long n;         /* numbers */
+};
+
+
+typedef struct ktap_value {
+       union _ktap_value val;
+       int type;
+} ktap_value;
+
+typedef ktap_value * StkId;
+
+
+
+typedef union ktap_udata {
+       struct {
+               CommonHeader;
+               size_t len;  /* number of bytes */
+       } uv;
+} ktap_udata;
+
+/*
+ * Description of an upvalue for function prototypes
+ */
+typedef struct ktap_upvaldesc {
+       ktap_string *name;  /* upvalue name (for debug information) */
+       u8 instack;  /* whether it is in stack */
+       u8 idx;  /* index of upvalue (in stack or in outer function's list) */
+} ktap_upvaldesc;
+
+/*
+ * Description of a local variable for function prototypes
+ * (used for debug information)
+ */
+typedef struct ktap_locvar {
+       ktap_string *varname;
+       int startpc;  /* first point where variable is active */
+       int endpc;    /* first point where variable is dead */
+} ktap_locvar;
+
+
+typedef struct ktap_upval {
+       CommonHeader;
+       ktap_value *v;  /* points to stack or to its own value */
+       union {
+               ktap_value value;  /* the value (when closed) */
+               struct {  /* double linked list (when open) */
+                       struct ktap_upval *prev;
+                       struct ktap_upval *next;
+               } l;
+       } u;
+} ktap_upval;
+
+
+#define KTAP_STACK_MAX_ENTRIES 10
+
+typedef struct ktap_btrace {
+       CommonHeader;
+       unsigned int nr_entries;
+       unsigned long entries[KTAP_STACK_MAX_ENTRIES];
+} ktap_btrace;
+
+#define ktap_closure_header \
+       CommonHeader; u8 nupvalues; ktap_gcobject *gclist
+
+typedef struct ktap_cclosure {
+       ktap_closure_header;
+       ktap_cfunction f;
+       ktap_value upvalue[1];  /* list of upvalues */
+} ktap_cclosure;
+
+
+typedef struct ktap_lclosure {
+       ktap_closure_header;
+       struct ktap_proto *p;
+       struct ktap_upval *upvals[1];  /* list of upvalues */
+} ktap_lclosure;
+
+
+typedef struct ktap_closure {
+       struct ktap_cclosure c;
+       struct ktap_lclosure l;
+} ktap_closure;
+
+
+typedef struct ktap_proto {
+       CommonHeader;
+       ktap_value *k;  /* constants used by the function */
+       ktap_instruction *code;
+       struct ktap_proto **p;  /* functions defined inside the function */
+       int *lineinfo;  /* map from opcodes to source lines (debug information) */
+       struct ktap_locvar *locvars;  /* information about local variables (debug information) */
+       struct ktap_upvaldesc *upvalues;  /* upvalue information */
+       ktap_closure *cache;  /* last created closure with this prototype */
+       ktap_string  *source;  /* used for debug information */
+       int sizeupvalues;  /* size of 'upvalues' */
+       int sizek;  /* size of `k' */
+       int sizecode;
+       int sizelineinfo;
+       int sizep;  /* size of `p' */
+       int sizelocvars;
+       int linedefined;
+       int lastlinedefined;
+       u8 numparams;  /* number of fixed parameters */
+       u8 is_vararg;
+       u8 maxstacksize;  /* maximum stack used by this function */
+} ktap_proto;
+
+
+/*
+ * information about a call
+ */
+typedef struct ktap_callinfo {
+       StkId func;  /* function index in the stack */
+       StkId top;  /* top for this function */
+       struct ktap_callinfo *prev, *next;  /* dynamic call link */
+       short nresults;  /* expected number of results from this function */
+       u8 callstatus;
+       int extra;
+       union {
+               struct {  /* only for Lua functions */
+                       StkId base;  /* base for this function */
+                       const unsigned int *savedpc;
+               } l;
+               struct {  /* only for C functions */
+                       int ctx;  /* context info. in case of yields */
+                       u8 status;
+               } c;
+       } u;
+} ktap_callinfo;
+
+
+/*
+ * ktap_tables
+ */
+typedef union ktap_tkey {
+       struct {
+               union _ktap_value value_;
+               int tt_;
+               struct ktap_tnode *next;  /* for chaining */
+       } nk;
+       ktap_value tvk;
+} ktap_tkey;
+
+
+typedef struct ktap_tnode {
+       ktap_value i_val;
+       ktap_tkey i_key;
+} ktap_tnode;
+
+
+typedef struct ktap_table {
+       CommonHeader;
+#ifdef __KERNEL__
+       arch_spinlock_t lock;
+#endif
+       u8 flags;  /* 1<<p means tagmethod(p) is not present */
+       u8 lsizenode;  /* log2 of size of `node' array */
+       int sizearray;  /* size of `array' array */
+       ktap_value *array;  /* array part */
+       ktap_tnode *node;
+       ktap_tnode *lastfree;  /* any free position is before this position */
+       ktap_gcobject *gclist;
+} ktap_table;
+
+#define lmod(s,size)   ((int)((s) & ((size)-1)))
+
+enum AGGREGATION_TYPE {
+       AGGREGATION_TYPE_COUNT,
+       AGGREGATION_TYPE_MAX,
+       AGGREGATION_TYPE_MIN,
+       AGGREGATION_TYPE_SUM,
+       AGGREGATION_TYPE_AVG
+};
+
+typedef struct ktap_aggrtable {
+       CommonHeader;
+       ktap_table **pcpu_tbl;
+       ktap_gcobject *gclist;
+} ktap_aggrtable;
+
+typedef struct ktap_aggraccval {
+       CommonHeader;
+       int type;
+       int val;
+       int more;
+} ktap_aggraccval;
+
+typedef struct ktap_stringtable {
+       ktap_gcobject **hash;
+       int nuse;
+       int size;
+} ktap_stringtable;
+
+typedef struct ktap_global_state {
+       ktap_stringtable strt;  /* hash table for strings */
+       ktap_value registry;
+       unsigned int seed; /* randonized seed for hashes */
+       u8 gcstate; /* state of garbage collector */
+       u8 gckind; /* kind of GC running */
+       u8 gcrunning; /* true if GC is running */
+
+       ktap_gcobject *allgc; /* list of all collectable objects */
+
+       ktap_upval uvhead; /* head of double-linked list of all open upvalues */
+
+       struct ktap_state *mainthread;
+#ifdef __KERNEL__
+       ktap_parm *parm;
+       pid_t trace_pid;
+       struct task_struct *trace_task;
+       cpumask_var_t cpumask;
+       struct ring_buffer *buffer;
+       struct dentry *trace_pipe_dentry;
+       int nr_builtin_cfunction;
+       ktap_value *cfunction_tbl;
+       struct task_struct *task;
+       int trace_enabled;
+       struct list_head timers;
+       struct list_head probe_events_head;
+       int exit;
+       int wait_user;
+       ktap_closure *trace_end_closure;
+#endif
+       int error;
+} ktap_global_state;
+
+typedef struct ktap_state {
+       CommonHeader;
+       u8 status;
+       ktap_global_state *g;
+       int stop;
+       StkId top;
+       ktap_callinfo *ci;
+       const unsigned long *oldpc;
+       StkId stack_last;
+       StkId stack;
+       int stacksize;
+       ktap_gcobject *openupval;
+       ktap_callinfo baseci;
+
+       int debug;
+       int version;
+       int gcrunning;
+
+       /* list of temp collectable objects, free when thread exit */
+       ktap_gcobject *gclist;
+
+#ifdef __KERNEL__
+       struct ktap_event *current_event;
+       int aggr_accval; /* for temp value storage */
+#endif
+} ktap_state;
+
+
+typedef struct gcheader {
+       CommonHeader;
+} gcheader;
+
+/*
+ * Union of all collectable objects
+ */
+union ktap_gcobject {
+       gcheader gch;  /* common header */
+       union ktap_string ts;
+       union ktap_udata u;
+       struct ktap_closure cl;
+       struct ktap_table h;
+       struct ktap_aggrtable ah;
+       struct ktap_aggraccval acc;
+       struct ktap_proto p;
+       struct ktap_upval uv;
+       struct ktap_state th;  /* thread */
+       struct ktap_btrace bt;  /* thread */
+};
+
+#define gch(o) (&(o)->gch)
+/* macros to convert a GCObject into a specific value */
+#define rawgco2ts(o)   (&((o)->ts))
+#define gco2ts(o)       (&rawgco2ts(o)->tsv)
+
+#define gco2uv(o)      (&((o)->uv))
+
+#define obj2gco(v)     ((ktap_gcobject *)(v))
+
+
+#ifdef __KERNEL__
+#define ktap_assert(s)
+#else
+#define ktap_assert(s)
+#if 0
+#define ktap_assert(s) \
+       do {    \
+               if (!s) {       \
+                       printf("assert failed %s, %d\n", __func__, __LINE__);\
+                       exit(0);        \
+               }       \
+       } while(0)
+#endif
+#endif
+
+#define check_exp(c,e)                (e)
+
+
+typedef int ktap_number;
+
+
+#define ktap_number2int(i,n)   ((i)=(int)(n))
+
+
+/* predefined values in the registry */
+#define KTAP_RIDX_MAINTHREAD     1
+#define KTAP_RIDX_GLOBALS        2
+#define KTAP_RIDX_LAST           KTAP_RIDX_GLOBALS
+
+
+#define KTAP_TNONE             (-1)
+
+#define KTAP_TNIL              0
+#define KTAP_TBOOLEAN          1
+#define KTAP_TLIGHTUSERDATA    2
+#define KTAP_TNUMBER           3
+#define KTAP_TSTRING           4
+#define KTAP_TSHRSTR           (KTAP_TSTRING | (0 << 4))  /* short strings */
+#define KTAP_TLNGSTR           (KTAP_TSTRING | (1 << 4))  /* long strings */
+#define KTAP_TTABLE            5
+#define KTAP_TFUNCTION         6
+#define KTAP_TLCL              (KTAP_TFUNCTION | (0 << 4))  /* closure */
+#define KTAP_TLCF              (KTAP_TFUNCTION | (1 << 4))  /* light C function */
+#define KTAP_TCCL              (KTAP_TFUNCTION | (2 << 4))  /* C closure */
+#define KTAP_TUSERDATA         7
+#define KTAP_TTHREAD           8
+
+#define KTAP_NUMTAGS           9
+
+#define KTAP_TPROTO            11
+#define KTAP_TUPVAL            12
+
+#define KTAP_TEVENT            13
+
+#define KTAP_TBTRACE           14
+
+#define KTAP_TAGGRTABLE                15
+#define KTAP_TAGGRACCVAL       16
+#define KTAP_TAGGRVAL          17
+
+#define ttype(o)       ((o->type) & 0x3F)
+#define settype(obj, t)        ((obj)->type = (t))
+
+
+
+/* raw type tag of a TValue */
+#define rttype(o)       ((o)->type)
+
+/* tag with no variants (bits 0-3) */
+#define novariant(x)    ((x) & 0x0F)
+
+/* type tag of a TValue with no variants (bits 0-3) */
+#define ttypenv(o)      (novariant(rttype(o)))
+
+#define val_(o)                ((o)->val)
+
+#define bvalue(o)      (val_(o).b)
+#define nvalue(o)      (val_(o).n)
+#define hvalue(o)      (&val_(o).gc->h)
+#define ahvalue(o)     (&val_(o).gc->ah)
+#define aggraccvalue(o)        (&val_(o).gc->acc)
+#define CLVALUE(o)     (&val_(o).gc->cl.l)
+#define clcvalue(o)    (&val_(o).gc->cl.c)
+#define clvalue(o)     (&val_(o).gc->cl)
+#define rawtsvalue(o)  (&val_(o).gc->ts)
+#define pvalue(o)      (&val_(o).p)
+#define fvalue(o)      (val_(o).f)
+#define rawuvalue(o)   (&val_(o).gc->u)
+#define uvalue(o)      (&rawuvalue(o)->uv)
+#define evalue(o)      (val_(o).p)
+#define btvalue(o)     (&val_(o).gc->bt)
+
+#define gcvalue(o)     (val_(o).gc)
+
+#define isnil(o)       (o->type == KTAP_TNIL)
+#define isboolean(o)   (o->type == KTAP_TBOOLEAN)
+#define isfalse(o)     (isnil(o) || (isboolean(o) && bvalue(o) == 0))
+
+#define ttisshrstring(o)       ((o)->type == KTAP_TSHRSTR)
+#define ttisstring(o)          (((o)->type & 0x0F) == KTAP_TSTRING)
+#define ttisnumber(o)          ((o)->type == KTAP_TNUMBER)
+#define ttisfunc(o)            ((o)->type == KTAP_TFUNCTION)
+#define ttistable(o)           ((o)->type == KTAP_TTABLE)
+#define ttisaggrtable(o)       ((o)->type == KTAP_TAGGRTABLE)
+#define ttisaggrval(o)         ((o)->type == KTAP_TAGGRVAL)
+#define ttisaggracc(o)         ((o)->type == KTAP_TAGGRACCVAL)
+#define ttisnil(o)             ((o)->type == KTAP_TNIL)
+#define ttisboolean(o)         ((o)->type == KTAP_TBOOLEAN)
+#define ttisequal(o1,o2)        ((o1)->type == (o2)->type)
+#define ttisevent(o)           ((o)->type == KTAP_TEVENT)
+#define ttisbtrace(o)          ((o)->type == KTAP_TBTRACE)
+
+#define ttisclone(o)           ttisbtrace(o)
+
+
+#define setnilvalue(obj) \
+       { ktap_value *io = (obj); io->val.n = 0; settype(io, KTAP_TNIL); }
+
+#define setbvalue(obj, x) \
+       { ktap_value *io = (obj); io->val.b = (x); settype(io, KTAP_TBOOLEAN); }
+
+#define setnvalue(obj, x) \
+       { ktap_value *io = (obj); io->val.n = (x); settype(io, KTAP_TNUMBER); }
+
+#define setaggrvalue(obj, x) \
+       { ktap_value *io = (obj); io->val.n = (x); settype(io, KTAP_TAGGRVAL); }
+
+#define setaggraccvalue(obj,x) \
+       { ktap_value *io=(obj); \
+         val_(io).gc = (ktap_gcobject *)(x); settype(io, KTAP_TAGGRACCVAL); }
+
+#define setsvalue(obj, x) \
+       { ktap_value *io = (obj); \
+         ktap_string *x_ = (x); \
+         io->val.gc = (ktap_gcobject *)x_; settype(io, x_->tsv.tt); }
+
+#define setcllvalue(obj, x) \
+       { ktap_value *io = (obj); \
+         io->val.gc = (ktap_gcobject *)x; settype(io, KTAP_TLCL); }
+
+#define sethvalue(obj,x) \
+       { ktap_value *io=(obj); \
+         val_(io).gc = (ktap_gcobject *)(x); settype(io, KTAP_TTABLE); }
+
+#define setahvalue(obj,x) \
+       { ktap_value *io=(obj); \
+         val_(io).gc = (ktap_gcobject *)(x); settype(io, KTAP_TAGGRTABLE); }
+
+#define setfvalue(obj,x) \
+       { ktap_value *io=(obj); val_(io).f=(x); settype(io, KTAP_TLCF); }
+
+#define setthvalue(L,obj,x) \
+       { ktap_value *io=(obj); \
+         val_(io).gc = (ktap_gcobject *)(x); settype(io, KTAP_TTHREAD); }
+
+#define setevalue(obj, x) \
+       { ktap_value *io=(obj); val_(io).p = (x); settype(io, KTAP_TEVENT); }
+
+#define setbtvalue(obj,x) \
+       { ktap_value *io=(obj); \
+         val_(io).gc = (ktap_gcobject *)(x); settype(io, KTAP_TBTRACE); }
+
+#define setobj(obj1,obj2) \
+        { const ktap_value *io2=(obj2); ktap_value *io1=(obj1); \
+          io1->val = io2->val; io1->type = io2->type; }
+
+#define rawequalobj(t1, t2) \
+       (ttisequal(t1, t2) && kp_equalobjv(NULL, t1, t2))
+
+#define equalobj(ks, t1, t2) rawequalobj(t1, t2)
+
+#define incr_top(ks) {ks->top++;}
+
+#define NUMADD(a, b)    ((a) + (b))
+#define NUMSUB(a, b)    ((a) - (b))
+#define NUMMUL(a, b)    ((a) * (b))
+#define NUMDIV(a, b)    ((a) / (b))
+#define NUMUNM(a)       (-(a))
+#define NUMEQ(a, b)     ((a) == (b))
+#define NUMLT(a, b)     ((a) < (b))
+#define NUMLE(a, b)     ((a) <= (b))
+#define NUMISNAN(a)     (!NUMEQ((a), (a)))
+
+/* todo: floor and pow in kernel */
+#define NUMMOD(a, b)    ((a) % (b))
+#define NUMPOW(a, b)    (pow(a, b))
+
+
+ktap_string *kp_tstring_newlstr(ktap_state *ks, const char *str, size_t l);
+ktap_string *kp_tstring_newlstr_local(ktap_state *ks, const char *str, size_t l);
+ktap_string *kp_tstring_new(ktap_state *ks, const char *str);
+ktap_string *kp_tstring_new_local(ktap_state *ks, const char *str);
+int kp_tstring_eqstr(ktap_string *a, ktap_string *b);
+unsigned int kp_string_hash(const char *str, size_t l, unsigned int seed);
+int kp_tstring_eqlngstr(ktap_string *a, ktap_string *b);
+int kp_tstring_cmp(const ktap_string *ls, const ktap_string *rs);
+void kp_tstring_resize(ktap_state *ks, int newsize);
+void kp_tstring_freeall(ktap_state *ks);
+
+ktap_value *kp_table_set(ktap_state *ks, ktap_table *t, const ktap_value *key);
+ktap_table *kp_table_new(ktap_state *ks);
+const ktap_value *kp_table_getint(ktap_table *t, int key);
+void kp_table_setint(ktap_state *ks, ktap_table *t, int key, ktap_value *v);
+const ktap_value *kp_table_get(ktap_table *t, const ktap_value *key);
+void kp_table_setvalue(ktap_state *ks, ktap_table *t, const ktap_value *key, ktap_value *val);
+void kp_table_resize(ktap_state *ks, ktap_table *t, int nasize, int nhsize);
+void kp_table_resizearray(ktap_state *ks, ktap_table *t, int nasize);
+void kp_table_free(ktap_state *ks, ktap_table *t);
+int kp_table_length(ktap_state *ks, ktap_table *t);
+void kp_table_dump(ktap_state *ks, ktap_table *t);
+void kp_table_clear(ktap_state *ks, ktap_table *t);
+void kp_table_histogram(ktap_state *ks, ktap_table *t);
+int kp_table_next(ktap_state *ks, ktap_table *t, StkId key);
+void kp_table_atomic_inc(ktap_state *ks, ktap_table *t, ktap_value *key, int n);
+void kp_aggraccval_dump(ktap_state *ks, ktap_aggraccval *acc);
+ktap_aggrtable *kp_aggrtable_new(ktap_state *ks);
+ktap_table *kp_aggrtable_synthesis(ktap_state *ks, ktap_aggrtable *ah);
+void kp_aggrtable_dump(ktap_state *ks, ktap_aggrtable *ah);
+void kp_aggrtable_free(ktap_state *ks, ktap_aggrtable *ah);
+void kp_aggrtable_set(ktap_state *ks, ktap_aggrtable *ah,
+                       ktap_value *key, ktap_value *val);
+void kp_aggrtable_get(ktap_state *ks, ktap_aggrtable *ah,
+                       ktap_value *key, ktap_value *val);
+void kp_aggrtable_histogram(ktap_state *ks, ktap_aggrtable *ah);
+void kp_obj_dump(ktap_state *ks, const ktap_value *v);
+void kp_showobj(ktap_state *ks, const ktap_value *v);
+int kp_objlen(ktap_state *ks, const ktap_value *rb);
+void kp_objclone(ktap_state *ks, const ktap_value *o, ktap_value *newo,
+                ktap_gcobject **list);
+ktap_gcobject *kp_newobject(ktap_state *ks, int type, size_t size, ktap_gcobject **list);
+int kp_equalobjv(ktap_state *ks, const ktap_value *t1, const ktap_value *t2);
+ktap_closure *kp_newlclosure(ktap_state *ks, int n);
+ktap_proto *kp_newproto(ktap_state *ks);
+ktap_upval *kp_newupval(ktap_state *ks);
+void kp_free_gclist(ktap_state *ks, ktap_gcobject *o);
+void kp_free_all_gcobject(ktap_state *ks);
+void kp_header(u8 *h);
+
+int kp_str2d(const char *s, size_t len, ktap_number *result);
+
+#define kp_realloc(ks, v, osize, nsize, t) \
+       ((v) = (t *)kp_reallocv(ks, v, osize * sizeof(t), nsize * sizeof(t)))
+
+#define kp_error(ks, args...) \
+       do { \
+               kp_printf(ks, "error: "args);   \
+               G(ks)->error = 1; \
+               kp_exit(ks);    \
+       } while(0)
+
+#ifdef __KERNEL__
+#define G(ks)   (ks->g)
+
+void *kp_malloc(ktap_state *ks, int size);
+void kp_free(ktap_state *ks, void *addr);
+void *kp_reallocv(ktap_state *ks, void *addr, int oldsize, int newsize);
+void *kp_zalloc(ktap_state *ks, int size);
+
+void kp_printf(ktap_state *ks, const char *fmt, ...);
+extern void __kp_puts(ktap_state *ks, const char *str);
+extern void __kp_bputs(ktap_state *ks, const char *str);
+
+#define kp_puts(ks, str) ({                                            \
+       static const char *trace_printk_fmt                             \
+               __attribute__((section("__trace_printk_fmt"))) =        \
+               __builtin_constant_p(str) ? str : NULL;                 \
+                                                                       \
+       if (__builtin_constant_p(str))                                  \
+               __kp_bputs(ks, trace_printk_fmt);               \
+       else                                                            \
+               __kp_puts(ks, str);             \
+})
+
+#else
+/*
+ * this is used for ktapc tstring operation, tstring need G(ks)->strt
+ * and G(ks)->seed, so ktapc need to init those field
+ */
+#define G(ks)   (&dummy_global_state)
+extern ktap_global_state dummy_global_state;
+
+#define kp_malloc(ks, size)                    malloc(size)
+#define kp_free(ks, block)                     free(block)
+#define kp_reallocv(ks, block, osize, nsize)   realloc(block, nsize)
+#define kp_printf(ks, args...)                 printf(args)
+#define kp_puts(ks, str)                       printf("%s", str)
+#define kp_exit(ks)                            exit(EXIT_FAILURE)
+#endif
+
+#define __maybe_unused __attribute__((unused))
+
+/*
+ * KTAP_QL describes how error messages quote program elements.
+ * CHANGE it if you want a different appearance.
+ */
+#define KTAP_QL(x)      "'" x "'"
+#define KTAP_QS         KTAP_QL("%s")
+
+#endif /* __KTAP_TYPES_H__ */
+
diff --git a/drivers/staging/ktap/interpreter/ktap.c b/drivers/staging/ktap/interpreter/ktap.c
new file mode 100644 (file)
index 0000000..18d8fc8
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * ktap.c - ktapvm kernel module main entry
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * this file is the first file to be compile, add CONFIG_ checking in here.
+ * See Requirements in doc/introduction.txt
+ */
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
+#error "Currently ktap don't support kernel older than 3.1"
+#endif
+
+#if !CONFIG_EVENT_TRACING
+#error "Please enable CONFIG_EVENT_TRACING before compile ktap"
+#endif
+
+#if !CONFIG_PERF_EVENTS
+#error "Please enable CONFIG_PERF_EVENTS before compile ktap"
+#endif
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/file.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/anon_inodes.h>
+#include <linux/debugfs.h>
+#include <linux/vmalloc.h>
+#include "../include/ktap.h"
+
+static int load_trunk(struct ktap_parm *parm, unsigned long **buff)
+{
+       int ret;
+       unsigned long *vmstart;
+
+       vmstart = vmalloc(parm->trunk_len);
+       if (!vmstart)
+               return -ENOMEM;
+
+       ret = copy_from_user(vmstart, (void __user *)parm->trunk,
+                            parm->trunk_len);
+       if (ret < 0) {
+               vfree(vmstart);
+               return -EFAULT;
+       }
+
+       *buff = vmstart;
+       return 0;
+}
+
+int gettimeofday_us(void)
+{
+       struct timeval tv;
+
+       do_gettimeofday(&tv);
+       return tv.tv_sec * USEC_PER_SEC + tv.tv_usec;
+}
+
+struct dentry *kp_dir_dentry;
+static atomic_t kp_is_running = ATOMIC_INIT(0);
+
+/* Ktap Main Entry */
+static int ktap_main(struct file *file, ktap_parm *parm)
+{
+       unsigned long *buff = NULL;
+       ktap_state *ks;
+       ktap_closure *cl;
+       int start_time, delta_time;
+       int ret;
+
+       if (atomic_inc_return(&kp_is_running) != 1) {
+               atomic_dec(&kp_is_running);
+               pr_info("only one ktap thread allow to run\n");
+               return -EBUSY;
+       }
+
+       start_time = gettimeofday_us();
+
+       ks = kp_newstate(parm, kp_dir_dentry);
+       if (unlikely(!ks)) {
+               ret = -ENOEXEC;
+               goto out;
+       }
+
+       file->private_data = ks;
+
+       ret = load_trunk(parm, &buff);
+       if (ret) {
+               pr_err("cannot load file\n");
+               goto out;
+       }
+
+       cl = kp_load(ks, (unsigned char *)buff);
+
+       vfree(buff);
+
+       if (cl) {
+               /* optimize bytecode before excuting */
+               kp_optimize_code(ks, 0, cl->l.p);
+
+               delta_time = gettimeofday_us() - start_time;
+               kp_verbose_printf(ks, "booting time: %d (us)\n", delta_time);
+               kp_call(ks, ks->top - 1, 0);
+       }
+
+       kp_final_exit(ks);
+
+ out:
+       atomic_dec(&kp_is_running);     
+       return ret;
+}
+
+
+static void print_version(void)
+{
+}
+
+static long ktap_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       ktap_parm parm;
+       int ret;
+
+       switch (cmd) {
+       case KTAP_CMD_IOC_VERSION:
+               print_version();
+               return 0;
+       case KTAP_CMD_IOC_RUN:
+               ret = copy_from_user(&parm, (void __user *)arg,
+                                    sizeof(ktap_parm));
+               if (ret < 0)
+                       return -EFAULT;
+
+               return ktap_main(file, &parm);
+       default:
+               return -EINVAL;
+       };
+
+        return 0;
+}
+
+static const struct file_operations ktap_fops = {
+       .llseek                 = no_llseek,
+       .unlocked_ioctl         = ktap_ioctl,
+};
+
+static long ktapvm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       int new_fd, err;
+       struct file *new_file;
+
+       new_fd = get_unused_fd();
+       if (new_fd < 0)
+               return new_fd;
+
+       new_file = anon_inode_getfile("[ktap]", &ktap_fops, NULL, O_RDWR);
+       if (IS_ERR(new_file)) {
+               err = PTR_ERR(new_file);
+               put_unused_fd(new_fd);
+               return err;
+       }
+
+       file->private_data = NULL;
+       fd_install(new_fd, new_file);
+       return new_fd;
+}
+
+static const struct file_operations ktapvm_fops = {
+       .owner  = THIS_MODULE,
+       .unlocked_ioctl         = ktapvm_ioctl,
+};
+
+unsigned int kp_stub_exit_instr;
+
+static int __init init_ktap(void)
+{
+       struct dentry *ktapvm_dentry;
+
+       kp_dir_dentry = debugfs_create_dir("ktap", NULL);
+       if (!kp_dir_dentry) {
+               pr_err("ktap: debugfs_create_dir failed\n");
+               return -1;
+       }
+
+       ktapvm_dentry = debugfs_create_file("ktapvm", 0444, kp_dir_dentry, NULL,
+                                           &ktapvm_fops);
+
+       if (!ktapvm_dentry) {
+               pr_err("ktapvm: cannot create ktapvm file\n");
+               debugfs_remove_recursive(kp_dir_dentry);
+               return -1;
+       }
+
+       SET_OPCODE(kp_stub_exit_instr, OP_EXIT);
+
+       return 0;
+}
+
+static void __exit exit_ktap(void)
+{
+       debugfs_remove_recursive(kp_dir_dentry);
+}
+
+module_init(init_ktap);
+module_exit(exit_ktap);
+
+MODULE_AUTHOR("Jovi Zhangwei <jovi.zhangwei@gmail.com>");
+MODULE_DESCRIPTION("ktap");
+MODULE_LICENSE("GPL");
+
+int kp_max_exec_count = 10000;
+module_param_named(max_exec_count, kp_max_exec_count, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(max_exec_count, "non-mainthread max instruction execution count");
+
diff --git a/drivers/staging/ktap/interpreter/library/ansilib.c b/drivers/staging/ktap/interpreter/library/ansilib.c
new file mode 100644 (file)
index 0000000..d058373
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * ansilib.c - ANSI escape sequences library
+ *
+ * http://en.wikipedia.org/wiki/ANSI_escape_code
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "../../include/ktap.h"
+
+/**
+ * function ansi.clear_screen - Move cursor to top left and clear screen.
+ *
+ * Description: Sends ansi code for moving cursor to top left and then the
+ * ansi code for clearing the screen from the cursor position to the end.
+ */
+
+static int ktap_lib_clear_screen(ktap_state *ks)
+{
+       kp_printf(ks, "\033[1;1H\033[J");
+       return 0;
+}
+
+/**
+ * function ansi.set_color - Set the ansi Select Graphic Rendition mode.
+ * @fg: Foreground color to set.
+ *
+ * Description: Sends ansi code for Select Graphic Rendition mode for the
+ * given forground color. Black (30), Blue (34), Green (32), Cyan (36),
+ * Red (31), Purple (35), Brown (33), Light Gray (37).
+ */
+
+static int ktap_lib_set_color(ktap_state *ks)
+{
+       int fg;
+
+       kp_arg_check(ks, 1, KTAP_TNUMBER);
+
+       fg = nvalue(kp_arg(ks, 1));
+       kp_printf(ks, "\033[%dm", fg);
+       return 0;
+}
+
+/**
+ * function ansi.set_color2 - Set the ansi Select Graphic Rendition mode.
+ * @fg: Foreground color to set.
+ * @bg: Background color to set.
+ *
+ * Description: Sends ansi code for Select Graphic Rendition mode for the
+ * given forground color, Black (30), Blue (34), Green (32), Cyan (36),
+ * Red (31), Purple (35), Brown (33), Light Gray (37) and the given
+ * background color, Black (40), Red (41), Green (42), Yellow (43),
+ * Blue (44), Magenta (45), Cyan (46), White (47).
+ */
+static int ktap_lib_set_color2(ktap_state *ks)
+{
+       int fg, bg;
+       
+       kp_arg_check(ks, 1, KTAP_TNUMBER);
+       kp_arg_check(ks, 2, KTAP_TNUMBER);
+
+       fg = nvalue(kp_arg(ks, 1));
+       bg = nvalue(kp_arg(ks, 2));
+       kp_printf(ks, "\033[%d;%dm", fg, bg);
+       return 0;
+}
+
+/**
+ * function ansi.set_color3 - Set the ansi Select Graphic Rendition mode.
+ * @fg: Foreground color to set.
+ * @bg: Background color to set.
+ * @attr: Color attribute to set.
+ *
+ * Description: Sends ansi code for Select Graphic Rendition mode for the
+ * given forground color, Black (30), Blue (34), Green (32), Cyan (36),
+ * Red (31), Purple (35), Brown (33), Light Gray (37), the given
+ * background color, Black (40), Red (41), Green (42), Yellow (43),
+ * Blue (44), Magenta (45), Cyan (46), White (47) and the color attribute
+ * All attributes off (0), Intensity Bold (1), Underline Single (4),
+ * Blink Slow (5), Blink Rapid (6), Image Negative (7).
+ */
+static int ktap_lib_set_color3(ktap_state *ks)
+{
+       int fg, bg, attr;
+
+       kp_arg_check(ks, 1, KTAP_TNUMBER);
+       kp_arg_check(ks, 2, KTAP_TNUMBER);
+       kp_arg_check(ks, 3, KTAP_TNUMBER);
+
+       fg = nvalue(kp_arg(ks, 1));
+       bg = nvalue(kp_arg(ks, 2));
+       attr = nvalue(kp_arg(ks, 3));
+
+       if (attr)
+               kp_printf(ks, "\033[%d;%d;%dm", fg, bg, attr);
+       else
+               kp_printf(ks, "\033[%d;%dm", fg, bg);
+       
+       return 0;
+}
+
+/**
+ * function ansi.reset_color - Resets Select Graphic Rendition mode.
+ *
+ * Description: Sends ansi code to reset foreground, background and color
+ * attribute to default values.
+ */
+static int ktap_lib_reset_color(ktap_state *ks)
+{
+       kp_printf(ks, "\033[0;0m");
+       return 0;
+}
+
+/**
+ * function ansi.new_line - Move cursor to new line.
+ *
+ * Description: Sends ansi code new line.
+ */
+static int ktap_lib_new_line (ktap_state *ks)
+{
+       kp_printf(ks, "\12");
+       return 0;
+}
+
+static const ktap_Reg ansi_funcs[] = {
+       {"clear_screen", ktap_lib_clear_screen},
+       {"set_color", ktap_lib_set_color},
+       {"set_color2", ktap_lib_set_color2},
+       {"set_color3", ktap_lib_set_color3},
+       {"reset_color", ktap_lib_reset_color},
+       {"new_line", ktap_lib_new_line},
+       {NULL}
+};
+
+void kp_init_ansilib(ktap_state *ks)
+{
+       kp_register_lib(ks, "ansi", ansi_funcs); 
+}
diff --git a/drivers/staging/ktap/interpreter/library/baselib.c b/drivers/staging/ktap/interpreter/library/baselib.c
new file mode 100644 (file)
index 0000000..4bcdc62
--- /dev/null
@@ -0,0 +1,455 @@
+/*
+ * baselib.c - ktapvm kernel module base library
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/hardirq.h>
+#include <linux/kallsyms.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/utsname.h>
+#include <linux/time.h>
+#include <linux/clocksource.h>
+#include <linux/ring_buffer.h>
+#include <linux/stacktrace.h>
+#include "../../include/ktap.h"
+
+static int ktap_lib_next(ktap_state *ks)
+{
+       ktap_table *t = hvalue(ks->top - 2);
+
+       if (kp_table_next(ks, t, ks->top-1)) {
+               ks->top += 1;
+               return 2;
+       } else {
+               ks->top -= 1;
+               setnilvalue(ks->top++);
+               return 1;
+       }
+}
+
+static int ktap_lib_pairs(ktap_state *ks)
+{
+       ktap_value *v = kp_arg(ks, 1);
+       ktap_table *t;
+
+       if (G(ks)->mainthread != ks) {
+               kp_error(ks, "only mainthread can call table pairs\n");
+               return -1;
+       }
+
+       if (ttistable(v)) {
+               t = hvalue(v);
+       } else if (ttisaggrtable(v)) {
+               t = kp_aggrtable_synthesis(ks, ahvalue(v));
+       } else if (isnil(v)) {
+               kp_error(ks, "table is nil in pairs\n");
+               return 0;
+       } else {
+               kp_error(ks, "wrong argument for pairs\n");
+               return 0;
+       }
+
+       setfvalue(ks->top++, ktap_lib_next);
+       sethvalue(ks->top++, t);
+       setnilvalue(ks->top++);
+       return 3;
+}
+
+static int ktap_lib_len(ktap_state *ks)
+{
+       int len = kp_objlen(ks, kp_arg(ks, 1));
+
+       if (len < 0)
+               return -1;
+
+       setnvalue(ks->top, len);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_print(ktap_state *ks)
+{
+       int i;
+       int n = kp_arg_nr(ks);
+
+       for (i = 1; i <= n; i++) {
+               ktap_value *arg = kp_arg(ks, i);
+               if (i > 1)
+                       kp_puts(ks, "\t");
+               kp_showobj(ks, arg);
+       }
+
+       kp_puts(ks, "\n");
+
+       return 0;
+}
+
+/* don't engage with tstring when printf, use buffer directly */
+static int ktap_lib_printf(ktap_state *ks)
+{
+       struct trace_seq *seq;
+
+       preempt_disable_notrace();
+
+       seq = kp_percpu_data(KTAP_PERCPU_DATA_BUFFER);
+       trace_seq_init(seq);
+
+       if (kp_strfmt(ks, seq))
+               return 0;
+
+       seq->buffer[seq->len] = '\0';
+       kp_transport_write(ks, seq->buffer, seq->len + 1);
+
+       preempt_enable_notrace();
+       return 0;
+}
+
+#ifdef CONFIG_STACKTRACE
+static int ktap_lib_print_backtrace(ktap_state *ks)
+{
+       kp_transport_print_backtrace(ks);
+       return 0;
+}
+#else
+static int ktap_lib_print_backtrace(ktap_state *ks)
+{
+       kp_error(ks, "Please enable CONFIG_STACKTRACE before use "
+                    "ktap print_backtrace\n");
+       return 0;
+}
+#endif
+
+static int ktap_lib_backtrace(ktap_state *ks)
+{
+       struct stack_trace trace;
+       ktap_btrace *bt;
+
+       bt = kp_percpu_data(KTAP_PERCPU_DATA_BTRACE);
+
+       trace.nr_entries = 0;
+       trace.skip = 10;
+       trace.max_entries = KTAP_STACK_MAX_ENTRIES;
+       trace.entries = &bt->entries[0];
+       save_stack_trace(&trace);
+
+       bt->nr_entries = trace.nr_entries;
+       setbtvalue(ks->top, bt);
+       incr_top(ks);
+       return 1;
+}
+
+extern unsigned long long ns2usecs(cycle_t nsec);
+static int ktap_lib_print_trace_clock(ktap_state *ks)
+{
+       unsigned long long t;
+       unsigned long secs, usec_rem;
+       u64 timestamp;
+
+       /* use ring buffer's timestamp */
+       timestamp = ring_buffer_time_stamp(G(ks)->buffer, smp_processor_id());
+
+       t = ns2usecs(timestamp);
+       usec_rem = do_div(t, USEC_PER_SEC);
+       secs = (unsigned long)t;
+
+       kp_printf(ks, "%5lu.%06lu\n", secs, usec_rem);
+
+       return 0;
+}
+
+static int ktap_lib_exit(ktap_state *ks)
+{
+       kp_exit(ks);
+
+       /* do not execute bytecode any more in this thread */
+       return -1;
+}
+
+static int ktap_lib_pid(ktap_state *ks)
+{
+       pid_t pid = task_tgid_vnr(current);
+
+       setnvalue(ks->top, (int)pid);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_tid(ktap_state *ks)
+{
+       pid_t pid = task_pid_vnr(current);
+
+       setnvalue(ks->top, (int)pid);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_execname(ktap_state *ks)
+{
+       ktap_string *ts = kp_tstring_new(ks, current->comm);
+       setsvalue(ks->top, ts);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_cpu(ktap_state *ks)
+{
+       setnvalue(ks->top, smp_processor_id());
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_num_cpus(ktap_state *ks)
+{
+       setnvalue(ks->top, num_online_cpus());
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_in_interrupt(ktap_state *ks)
+{
+       int ret = in_interrupt();
+
+       setnvalue(ks->top, ret);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_arch(ktap_state *ks)
+{
+       setsvalue(ks->top, kp_tstring_new(ks, utsname()->machine));
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_kernel_v(ktap_state *ks)
+{
+       setsvalue(ks->top, kp_tstring_new(ks, utsname()->release));
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_user_string(ktap_state *ks)
+{
+       unsigned long addr;
+       char str[256] = {0};
+       int ret;
+
+       kp_arg_check(ks, 1, KTAP_TNUMBER);
+
+       addr = nvalue(kp_arg(ks, 1));
+
+       pagefault_disable();
+       ret = __copy_from_user_inatomic((void *)str, (const void *)addr, 256);
+       (void) &ret;  /* Silence compiler warning. */
+       pagefault_enable();
+       str[255] = '\0';
+       setsvalue(ks->top, kp_tstring_new(ks, str));
+
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_histogram(ktap_state *ks)
+{
+       ktap_value *v = kp_arg(ks, 1);
+
+       if (G(ks)->mainthread != ks) {
+               kp_error(ks, "only mainthread can call table historgram\n");
+               return -1;
+       }
+
+       if (ttistable(v))
+               kp_table_histogram(ks, hvalue(v));
+       else if (ttisaggrtable(v))
+               kp_aggrtable_histogram(ks, ahvalue(v));
+
+       return 0;
+}
+
+static int ktap_lib_aggr_table(ktap_state *ks)
+{
+       ktap_aggrtable *ah;
+
+       ah = kp_aggrtable_new(ks);
+       setahvalue(ks->top, ah);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_aggr_count(ktap_state *ks)
+{
+       setaggrvalue(ks->top, AGGREGATION_TYPE_COUNT);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_aggr_max(ktap_state *ks)
+{
+       kp_arg_check(ks, 1, KTAP_TNUMBER);
+
+       ks->aggr_accval = nvalue(kp_arg(ks, 1));
+       setaggrvalue(ks->top, AGGREGATION_TYPE_MAX);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_aggr_min(ktap_state *ks)
+{
+       kp_arg_check(ks, 1, KTAP_TNUMBER);
+
+       ks->aggr_accval = nvalue(kp_arg(ks, 1));
+       setaggrvalue(ks->top, AGGREGATION_TYPE_MIN);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_aggr_sum(ktap_state *ks)
+{
+       kp_arg_check(ks, 1, KTAP_TNUMBER);
+
+       ks->aggr_accval = nvalue(kp_arg(ks, 1));
+       setaggrvalue(ks->top, AGGREGATION_TYPE_SUM);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_aggr_avg(ktap_state *ks)
+{
+       kp_arg_check(ks, 1, KTAP_TNUMBER);
+
+       ks->aggr_accval = nvalue(kp_arg(ks, 1));
+       setaggrvalue(ks->top, AGGREGATION_TYPE_AVG);
+       incr_top(ks);
+       return 1;
+}
+
+static int ktap_lib_delete(ktap_state *ks)
+{
+       kp_arg_check(ks, 1, KTAP_TTABLE);
+
+       kp_table_clear(ks, hvalue(kp_arg(ks, 1)));
+       return 0;
+}
+
+static int ktap_lib_gettimeofday_us(ktap_state *ks)
+{
+       setnvalue(ks->top, gettimeofday_us());
+       incr_top(ks);
+
+       return 1;
+}
+
+/*
+ * use gdb to get field offset of struct task_struct, for example:
+ *
+ * gdb vmlinux
+ * (gdb)p &(((struct task_struct *)0).prio)
+ */
+static int ktap_lib_curr_task_info(ktap_state *ks)
+{
+       int offset;
+       int fetch_bytes;
+
+       kp_arg_check(ks, 1, KTAP_TNUMBER);
+
+       offset = nvalue(kp_arg(ks, 1));
+       
+       if (kp_arg_nr(ks) == 1)
+               fetch_bytes = 4; /* default fetch 4 bytes*/
+       else {
+               kp_arg_check(ks, 2, KTAP_TNUMBER);
+               fetch_bytes = nvalue(kp_arg(ks, 2));
+       }
+
+       if (offset >= sizeof(struct task_struct)) {
+               setnilvalue(ks->top++);
+               kp_error(ks, "access out of bound value of task_struct\n");
+               return 1;
+       }
+
+#define RET_VALUE ((unsigned long)current + offset)
+
+       switch (fetch_bytes) {
+       case 4:
+               setnvalue(ks->top, *(unsigned int *)RET_VALUE);
+               break;
+       case 8:
+               setnvalue(ks->top, *(unsigned long *)RET_VALUE);
+               break;
+       default:
+               kp_error(ks, "unsupported fetch bytes in curr_task_info\n");
+               setnilvalue(ks->top);
+               break;
+       }
+
+#undef RET_VALUE
+
+       incr_top(ks);
+       return 1;
+}
+
+/*
+ * This built-in function mainly purpose scripts/schedule/schedtimes.kp
+ */
+static int ktap_lib_in_iowait(ktap_state *ks)
+{
+       setnvalue(ks->top, current->in_iowait);
+       incr_top(ks);
+
+       return 1;
+}
+
+static const ktap_Reg base_funcs[] = {
+       {"pairs", ktap_lib_pairs},
+       {"len", ktap_lib_len},
+       {"print", ktap_lib_print},
+       {"printf", ktap_lib_printf},
+       {"print_backtrace", ktap_lib_print_backtrace},
+       {"backtrace", ktap_lib_backtrace},
+       {"print_trace_clock", ktap_lib_print_trace_clock},
+       {"in_interrupt", ktap_lib_in_interrupt},
+       {"exit", ktap_lib_exit},
+       {"pid", ktap_lib_pid},
+       {"tid", ktap_lib_tid},
+       {"execname", ktap_lib_execname},
+       {"cpu", ktap_lib_cpu},
+       {"num_cpus", ktap_lib_num_cpus},
+       {"arch", ktap_lib_arch},
+       {"kernel_v", ktap_lib_kernel_v},
+       {"user_string", ktap_lib_user_string},
+       {"histogram", ktap_lib_histogram},
+       {"aggr_table", ktap_lib_aggr_table},
+       {"count", ktap_lib_aggr_count},
+       {"max", ktap_lib_aggr_max},
+       {"min", ktap_lib_aggr_min},
+       {"sum", ktap_lib_aggr_sum},
+       {"avg", ktap_lib_aggr_avg},
+
+       {"delete", ktap_lib_delete},
+       {"gettimeofday_us", ktap_lib_gettimeofday_us},
+       {"curr_taskinfo", ktap_lib_curr_task_info},
+       {"in_iowait", ktap_lib_in_iowait},
+       {NULL}
+};
+
+void kp_init_baselib(ktap_state *ks)
+{
+       kp_register_lib(ks, NULL, base_funcs); 
+}
diff --git a/drivers/staging/ktap/interpreter/library/kdebug.c b/drivers/staging/ktap/interpreter/library/kdebug.c
new file mode 100644 (file)
index 0000000..a9477be
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * kdebug.c - ktap probing core implementation
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/version.h>
+#include <linux/ftrace_event.h>
+#include "../../include/ktap.h"
+
+static void ktap_call_probe_closure(ktap_state *mainthread, ktap_closure *cl,
+                                   struct ktap_event *e)
+{
+       ktap_state *ks;
+       ktap_value *func;
+
+       ks = kp_newthread(mainthread);
+       setcllvalue(ks->top, cl);
+       func = ks->top;
+       incr_top(ks);
+
+       ks->current_event = e;
+
+       kp_call(ks, func, 0);
+
+       ks->current_event = NULL;
+       kp_exitthread(ks);
+}
+
+void kp_event_tostring(ktap_state *ks, struct trace_seq *seq)
+{
+       struct ktap_event *e = ks->current_event;
+       struct trace_iterator *iter;
+       struct trace_event *ev;
+       enum print_line_t ret = TRACE_TYPE_NO_CONSUME;
+
+       /* Simulate the iterator */
+
+       /*
+        * use temp percpu buffer as trace_iterator
+        * we cannot use same temp buffer as printf.
+        */
+       iter = kp_percpu_data(KTAP_PERCPU_DATA_BUFFER2);
+
+       trace_seq_init(&iter->seq);
+       iter->ent = e->entry;
+
+       ev = &(e->call->event);
+       if (ev)
+               ret = ev->funcs->trace(iter, 0, ev);
+
+       if (ret != TRACE_TYPE_NO_CONSUME) {
+               struct trace_seq *s = &iter->seq;
+               int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
+
+               s->buffer[len] = '\0';
+               trace_seq_puts(seq, s->buffer);
+       }
+}
+
+#if 0
+/* check pt_regs defintion in linux/arch/x86/include/asm/ptrace.h */
+/* support other architecture pt_regs showing */
+static void event_regstr(ktap_state *ks, struct ktap_event *e, StkId ra)
+{
+       struct pt_regs *regs = e->regs;
+       char str[256] = {0};
+
+#if defined(CONFIG_X86_32)
+       snprintf(str, sizeof(str),
+               "{ax: 0x%lx, orig_ax: 0x%lx, bx: 0x%lx, cx: 0x%lx, dx: 0x%lx, "
+               "si: 0x%lx, di: 0x%lx, bp: 0x%lx, ds: 0x%lx, es: 0x%lx, fs: 0x%lx, "
+               "gs: 0x%lx, ip: 0x%lx, cs: 0x%lx, flags: 0x%lx, sp: 0x%lx, ss: 0x%lx}\n",
+               regs->ax, regs->orig_ax, regs->bx, regs->cx, regs->dx,
+               regs->si, regs->di, regs->bp, regs->ds, regs->es, regs->fs,
+               regs->gs, regs->ip, regs->cs, regs->flags, regs->sp, regs->ss);
+#elif defined(CONFIG_X86_64)
+       /* x86_64 pt_regs doesn't have ds, es, fs or gs. */
+       snprintf(str, sizeof(str),
+               "{ax: 0x%lx, orig_ax: 0x%lx, bx: 0x%lx, cx: 0x%lx, dx: 0x%lx, "
+               "si: 0x%lx, di: 0x%lx, r8: 0x%lx, r9: 0x%lx, r10: 0x%lx, r11: 0x%lx, "
+               "r12: 0x%lx, r13: 0x%lx, r14: 0x%lx, r15: 0x%lx, bp: 0x%lx, ip: 0x%lx, "
+               "cs: 0x%lx, flags: 0x%lx, sp: 0x%lx, ss: 0x%lx}\n",
+               regs->ax, regs->orig_ax, regs->bx, regs->cx, regs->dx,
+               regs->si, regs->di, regs->r8, regs->r9, regs->r10, regs->r11,
+               regs->r12, regs->r13, regs->r14, regs->r15, regs->bp, regs->ip,
+               regs->cs, regs->flags, regs->sp, regs->ss);
+#endif
+       setsvalue(ra, kp_tstring_new_local(ks, str));
+}
+#endif
+
+/***************************/
+/* This definition should keep update with kernel/trace/trace.h */
+struct ftrace_event_field {
+       struct list_head        link;
+       const char              *name;
+       const char              *type;
+       int                     filter_type;
+       int                     offset;
+       int                     size;
+       int                     is_signed;
+};
+
+static struct list_head *ktap_get_fields(struct ftrace_event_call *event_call)
+{
+       if (!event_call->class->get_fields)
+               return &event_call->class->fields;
+       return event_call->class->get_fields(event_call);
+}
+
+static void get_field_value(ktap_state *ks, struct ktap_event *e,
+                           struct ftrace_event_field *field, ktap_value *ra)
+{
+       void *value = (unsigned char *)e->entry + field->offset;
+
+       if (field->size == 4) {
+               int n = *(int *)value;
+               setnvalue(ra, n);
+               return;
+       } else if (field->size == 8) {
+               long n = *(long *)value;
+               setnvalue(ra, n);
+               return;
+       }
+
+       if (!strncmp(field->type, "char", 4)) {
+               setsvalue(ra, kp_tstring_new(ks, (char *)value));
+               return;
+       }
+}
+
+void kp_event_getarg(ktap_state *ks, ktap_value *ra, int n)
+{
+       struct ktap_event *e = ks->current_event;
+       int index = n;
+       struct ftrace_event_field *field;
+       struct list_head *head;
+
+       /* this is very slow and not safe, fix it in future */
+       head = ktap_get_fields(e->call);
+       list_for_each_entry_reverse(field, head, link) {
+               if (--index == 0) {
+                       get_field_value(ks, e, field, ra);
+                       return;
+               }
+       }
+
+       setnilvalue(ra);
+       return;
+}
+
+/* Callback function for perf event subsystem
+ * make ktap reentrant, don't disable irq in callback function,
+ * same as perf and ftrace. to make reentrant, we need some
+ * percpu data to be context isolation(irq/sirq/nmi/process)
+ *
+ * perf callback already consider on the recursion issue,
+ * so ktap don't need to check again in here.
+ *
+ * Note tracepoint handler is calling with rcu_read_lock.
+ */
+static void ktap_overflow_callback(struct perf_event *event,
+                                  struct perf_sample_data *data,
+                                  struct pt_regs *regs)
+{
+       struct ktap_probe_event *ktap_pevent;
+       struct ktap_event e;
+       ktap_state  *ks;
+       int rctx;
+
+       ktap_pevent = event->overflow_handler_context;
+       ks = ktap_pevent->ks;
+
+       if (unlikely(ks->stop))
+               return;
+
+       rctx = get_recursion_context();
+       if (rctx < 0)
+               return;
+
+       /* profile perf event don't have valid associated tp_event */
+       if (event->tp_event) {
+               e.call = event->tp_event;
+               e.entry = data->raw->data;
+               e.entry_size = data->raw->size;
+       }
+       e.pevent = ktap_pevent;
+       e.regs = regs;
+
+       ktap_call_probe_closure(ks, ktap_pevent->cl, &e);
+
+       put_recursion_context(rctx);
+}
+
+static void perf_destructor(struct ktap_probe_event *ktap_pevent)
+{
+       perf_event_release_kernel(ktap_pevent->perf);
+}
+
+static int (*kp_ftrace_profile_set_filter)(struct perf_event *event,
+                                          int event_id, char *filter_str);
+
+/*
+ * Generic perf event register function
+ * used by tracepoints/kprobe/uprobe/profile-timer/hw_breakpoint.
+ */
+void kp_perf_event_register(ktap_state *ks, struct perf_event_attr *attr,
+                           struct task_struct *task, char *filter,
+                           ktap_closure *cl)
+{
+       struct ktap_probe_event *ktap_pevent;
+       struct perf_event *event;
+       int cpu, ret;
+
+       kp_verbose_printf(ks, "enable perf event id: %d, filter: %s "
+                             "pid: %d\n", attr->config, filter,
+                             task ? task_tgid_vnr(task) : -1);
+
+       /*
+        * don't tracing until ktap_wait, the reason is:
+        * 1). some event may hit before apply filter
+        * 2). more simple to manage tracing thread
+        * 3). avoid race with mainthread.
+        *
+        * Another way to do this is make attr.disabled as 1, then use
+        * perf_event_enable after filter apply, however, perf_event_enable
+        * was not exported in kernel older than 3.3, so we drop this method.
+        */
+       ks->stop = 1;
+
+       for_each_cpu(cpu, G(ks)->cpumask) {
+               ktap_pevent = kp_zalloc(ks, sizeof(*ktap_pevent));
+               ktap_pevent->ks = ks;
+               ktap_pevent->cl = cl;
+               event = perf_event_create_kernel_counter(attr, cpu, task,
+                                                        ktap_overflow_callback,
+                                                        ktap_pevent);
+               if (IS_ERR(event)) {
+                       int err = PTR_ERR(event);
+                       kp_error(ks, "unable register perf event %d on cpu %d, "
+                                    "err: %d\n", attr->config, cpu, err);
+                       kp_free(ks, ktap_pevent);
+                       return;
+               }
+
+               ktap_pevent->perf = event;
+               INIT_LIST_HEAD(&ktap_pevent->list);
+               list_add_tail(&ktap_pevent->list, &G(ks)->probe_events_head);
+
+               if (!filter)
+                       continue;
+
+               ret = kp_ftrace_profile_set_filter(event, attr->config, filter);
+               if (ret) {
+                       kp_error(ks, "unable set filter %s for event id %d, "
+                                    "ret: %d\n", filter, attr->config, ret);
+                       perf_destructor(ktap_pevent);
+                       list_del(&ktap_pevent->list);
+                       kp_free(ks, ktap_pevent);
+                       return;
+               }
+       }
+}
+
+static void end_probes(struct ktap_state *ks)
+{
+       struct ktap_probe_event *ktap_pevent;
+       struct list_head *tmp, *pos;
+       struct list_head *head = &G(ks)->probe_events_head;
+
+       list_for_each(pos, head) {
+               ktap_pevent = container_of(pos, struct ktap_probe_event,
+                                          list);
+               perf_destructor(ktap_pevent);
+        }
+               /*
+        * Ensure our callback won't be called anymore. The buffers
+        * will be freed after that.
+        */
+       tracepoint_synchronize_unregister();
+
+       list_for_each_safe(pos, tmp, head) {
+               ktap_pevent = container_of(pos, struct ktap_probe_event,
+                                          list);
+               list_del(&ktap_pevent->list);
+               kp_free(ks, ktap_pevent);
+       }
+}
+
+static int ktap_lib_probe_by_id(ktap_state *ks)
+{
+       const char *ids_str;
+       char *start;
+       ktap_closure *cl;
+       struct task_struct *task = G(ks)->trace_task;
+       char filter_str[128] = {0};
+       char *filter, *ptr1, *sep, *ptr;
+
+       kp_arg_check(ks, 1, KTAP_TSTRING);
+       kp_arg_check(ks, 2, KTAP_TFUNCTION);
+
+       ids_str = svalue(kp_arg(ks, 1));
+       cl = clvalue(kp_arg(ks, 2));
+
+       start = (char *)ids_str;
+
+ again:
+       filter = NULL;
+
+       sep = strchr(start, ',');
+       if (!sep)
+               ptr1 = strchr(start, '/');
+       else
+               ptr1 = strnchr(start, sep - start, '/');
+
+       if (ptr1) {
+               char *ptr2 = strrchr(ptr1 + 1, '/');
+
+               if (ptr2) {
+                       memset(filter_str, 0, sizeof(filter_str));
+                       strncpy(filter_str, ptr1 + 1, ptr2 - ptr1 - 1);
+                       filter = &filter_str[0];
+               } else {
+                       kp_printf(ks, "cannot parse ids_str: %s\n", ids_str);
+                       return -1;
+               }
+       }
+
+       for (ptr = start; *ptr != ',' && *ptr != '\0' && *ptr != '/'; ptr++) {
+               char token[32] = {0};
+               int id;
+               int i = 0;
+
+               if (*ptr == ' ')
+                       continue;
+
+               while (isdigit(*ptr)) {
+                       token[i++] = *ptr++;
+               }
+
+               if (!kstrtoint(token, 10, &id)) {
+                       struct perf_event_attr attr;
+
+                       memset(&attr, 0, sizeof(attr));
+                       attr.type = PERF_TYPE_TRACEPOINT;       
+                       attr.config = id;
+                       attr.sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
+                                          PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD;
+                       attr.sample_period = 1;
+                       attr.size = sizeof(attr);
+                       attr.disabled = 0;
+
+                       kp_perf_event_register(ks, &attr, task, filter, cl);
+               }
+       }
+
+       if (sep && (*(sep + 1) != '\0')) {
+               start = sep + 1;
+               goto again;
+       }
+
+       return 0;
+}
+
+static int ktap_lib_probe_end(ktap_state *ks)
+{
+       kp_arg_check(ks, 1, KTAP_TFUNCTION);
+
+       G(ks)->trace_end_closure = clvalue(kp_arg(ks, 1));
+       return 0;
+}
+
+static int ktap_lib_traceoff(ktap_state *ks)
+{
+       end_probes(ks);
+
+       /* call trace_end_closure after probed end */
+       if (G(ks)->trace_end_closure) {
+               setcllvalue(ks->top, G(ks)->trace_end_closure);
+               incr_top(ks);
+               kp_call(ks, ks->top - 1, 0);
+               G(ks)->trace_end_closure = NULL;
+       }
+
+       return 0;
+}
+
+void kp_probe_exit(ktap_state *ks)
+{
+       if (!G(ks)->trace_enabled)
+               return;
+
+       end_probes(ks);
+
+       /* call trace_end_closure after probed end */
+       if (!G(ks)->error && G(ks)->trace_end_closure) {
+               setcllvalue(ks->top, G(ks)->trace_end_closure);
+               incr_top(ks);
+               kp_call(ks, ks->top - 1, 0);
+               G(ks)->trace_end_closure = NULL;
+       }
+
+       G(ks)->trace_enabled = 0;
+}
+
+int kp_probe_init(ktap_state *ks)
+{
+       G(ks)->trace_enabled = 1;
+       return 0;
+}
+
+static const ktap_Reg kdebuglib_funcs[] = {
+       {"probe_by_id", ktap_lib_probe_by_id},
+       {"probe_end", ktap_lib_probe_end},
+       {"traceoff", ktap_lib_traceoff},
+       {NULL}
+};
+
+void kp_init_kdebuglib(ktap_state *ks)
+{
+       kp_ftrace_profile_set_filter =
+               (void *)kallsyms_lookup_name("ftrace_profile_set_filter");
+       if (!kp_ftrace_profile_set_filter) {
+               printk("ktap: cannot lookup ftrace_profile_set_filter "
+                      "in kallsyms\n");
+               return;
+       }
+
+       kp_register_lib(ks, "kdebug", kdebuglib_funcs);
+}
+
diff --git a/drivers/staging/ktap/interpreter/library/timer.c b/drivers/staging/ktap/interpreter/library/timer.c
new file mode 100644 (file)
index 0000000..759f917
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * timer.c - timer library support for ktap
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/ctype.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include "../../include/ktap.h"
+
+struct hrtimer_ktap {
+       struct hrtimer timer;
+       ktap_state *ks;
+       ktap_closure *cl;
+       u64 ns;
+       struct list_head list;
+};
+
+/*
+ * Currently ktap disallow tracing event in timer callback closure,
+ * that will corrupt ktap_state and ktap stack, because timer closure
+ * and event closure use same irq percpu ktap_state and stack.
+ * We can use a different percpu ktap_state and stack for timer purpuse,
+ * but that's don't bring any big value with cost on memory consuming.
+ *
+ * So just simply disable tracing in timer closure,
+ * get_recursion_context()/put_recursion_context() is used for this purpose.
+ *
+ * option: export perf_swevent_put_recursion_context to slove this issue.
+ */
+static enum hrtimer_restart hrtimer_ktap_fn(struct hrtimer *timer)
+{
+       struct hrtimer_ktap *t;
+       ktap_state *ks;
+       int rctx;
+
+       rcu_read_lock_sched_notrace();
+       rctx = get_recursion_context();
+
+       t = container_of(timer, struct hrtimer_ktap, timer);
+
+       ks = kp_newthread(t->ks);
+       setcllvalue(ks->top, t->cl);
+       incr_top(ks);
+       kp_call(ks, ks->top - 1, 0);
+       kp_exitthread(ks);
+
+       hrtimer_add_expires_ns(timer, t->ns);
+
+       put_recursion_context(rctx);
+       rcu_read_unlock_sched_notrace();
+
+       return HRTIMER_RESTART;
+}
+
+static void set_tick_timer(ktap_state *ks, u64 period, ktap_closure *cl)
+{
+       struct hrtimer_ktap *t;
+
+       t = kp_malloc(ks, sizeof(*t));
+       t->ks = ks;
+       t->cl = cl;
+       t->ns = period;
+
+       INIT_LIST_HEAD(&t->list);
+       list_add(&t->list, &(G(ks)->timers));
+
+       hrtimer_init(&t->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       t->timer.function = hrtimer_ktap_fn;
+       hrtimer_start(&t->timer, ns_to_ktime(period), HRTIMER_MODE_REL);
+}
+
+static void set_profile_timer(ktap_state *ks, u64 period, ktap_closure *cl)
+{
+       struct perf_event_attr attr;
+
+       memset(&attr, 0, sizeof(attr));
+       attr.type = PERF_TYPE_SOFTWARE;
+       attr.config = PERF_COUNT_SW_CPU_CLOCK;
+       attr.sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
+                          PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD;
+       attr.sample_period = period;
+       attr.size = sizeof(attr);
+       attr.disabled = 0;
+
+       kp_perf_event_register(ks, &attr, NULL, NULL, cl);
+}
+
+static int do_tick_profile(ktap_state *ks, int is_tick)
+{
+       const char *str, *tmp;
+       char interval_str[32] = {0};
+       char suffix[10] = {0};
+       int n, i = 0;
+       int factor;
+
+       kp_arg_check(ks, 1, KTAP_TSTRING);
+       kp_arg_check(ks, 2, KTAP_TFUNCTION);
+
+       str = svalue(kp_arg(ks, 1));
+       tmp = str;
+       while (isdigit(*tmp))
+               tmp++;
+
+       strncpy(interval_str, str, tmp - str);
+       if (kstrtoint(interval_str, 10, &n))
+               goto error;
+
+       strncpy(suffix, tmp, 9);
+       while (suffix[i] != ' ' && suffix[i] != '\0')
+               i++;
+
+       suffix[i] = '\0';
+
+       if (!strcmp(suffix, "s") || !strcmp(suffix, "sec"))
+               factor = NSEC_PER_SEC;
+       else if (!strcmp(suffix, "ms") || !strcmp(suffix, "msec"))
+               factor = NSEC_PER_MSEC;
+       else if (!strcmp(suffix, "us") || !strcmp(suffix, "usec"))
+               factor = NSEC_PER_USEC;
+       else
+               goto error;
+
+       if (is_tick)
+               set_tick_timer(ks, (u64)factor * n, clvalue(kp_arg(ks, 2)));
+       else
+               set_profile_timer(ks, (u64)factor * n, clvalue(kp_arg(ks, 2)));
+
+       return 0;
+
+ error:
+       kp_error(ks, "cannot parse timer interval: %s\n", str);
+       return -1;
+}
+
+/*
+ * tick-n probes fire on only one CPU per interval.
+ * valid time suffixes: sec/s, msec/ms, usec/us
+ */
+static int ktap_lib_tick(ktap_state *ks)
+{
+       return do_tick_profile(ks, 1);
+}
+
+/*
+ * A profile-n probe fires every fixed interval on every CPU
+ * valid time suffixes: sec/s, msec/ms, usec/us
+ */
+static int ktap_lib_profile(ktap_state *ks)
+{
+       return do_tick_profile(ks, 0);
+}
+
+void kp_exit_timers(ktap_state *ks)
+{
+       struct hrtimer_ktap *t, *tmp;
+       struct list_head *timers_list = &(G(ks)->timers);
+
+       list_for_each_entry_safe(t, tmp, timers_list, list) {
+               hrtimer_cancel(&t->timer);
+               kp_free(ks, t);
+       }
+}
+
+static const ktap_Reg timerlib_funcs[] = {
+       {"profile",     ktap_lib_profile},
+       {"tick",        ktap_lib_tick},
+       {NULL}
+};
+
+void kp_init_timerlib(ktap_state *ks)
+{
+       kp_register_lib(ks, "timer", timerlib_funcs);
+}
+
diff --git a/drivers/staging/ktap/interpreter/loader.c b/drivers/staging/ktap/interpreter/loader.c
new file mode 100644 (file)
index 0000000..0da54d7
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * loader.c - loader for ktap bytecode chunk file
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/slab.h>
+#include "../include/ktap.h"
+
+#define KTAPC_TAIL     "\x19\x93\r\n\x1a\n"
+
+struct load_state {
+       unsigned char *buff;
+       int pos;
+       ktap_state *ks;
+};
+
+#define READ_CHAR(S)  (S->buff[S->pos++])
+#define READ_BYTE(S)  READ_CHAR(S)
+#define READ_INT(S)  load_int(S)
+#define READ_NUMBER(S) load_number(S)
+#define READ_STRING(S) load_string(S)
+#define READ_VECTOR(S, dst, size)  \
+       do {    \
+               memcpy(dst, &S->buff[S->pos], size);    \
+               S->pos += size; \
+       } while(0)
+
+#define NEW_VECTOR(S, size)    kp_malloc(S->ks, size)
+#define GET_CURRENT(S)         &S->buff[S->pos]
+#define ADD_POS(S, size)       S->pos += size
+
+
+static int load_function(struct load_state *S, ktap_proto *f);
+
+
+static int load_int(struct load_state *S)
+{
+       int x;
+
+       READ_VECTOR(S, &x, sizeof(int));
+       return x;
+}
+
+static int load_number(struct load_state *S)
+{
+       int x;
+
+       READ_VECTOR(S, &x, sizeof(ktap_number));
+       return x;
+}
+
+static ktap_string *load_string(struct load_state *S)
+{
+       ktap_string *ts;
+       size_t size;
+
+       size = READ_INT(S);
+
+       if (!size)
+               return NULL;
+       else {
+               char *s = GET_CURRENT(S);
+               ADD_POS(S, size);
+               /* remove trailing '\0' */
+               ts = kp_tstring_newlstr(S->ks, s, size - 1);
+               return ts;
+       }
+}
+
+
+static int load_code(struct load_state *S, ktap_proto *f)
+{
+       int n = READ_INT(S);
+
+       f->sizecode = n;
+       f->code = NEW_VECTOR(S, n * sizeof(ktap_instruction));
+       READ_VECTOR(S, f->code, n * sizeof(ktap_instruction));
+
+       return 0;
+}
+
+static int load_constants(struct load_state *S, ktap_proto *f)
+{
+       int i,n;
+
+       n = READ_INT(S);
+
+       f->sizek = n;
+       f->k = NEW_VECTOR(S, n * sizeof(ktap_value));
+       for (i = 0; i < n; i++)
+               setnilvalue(&f->k[i]);
+
+       for (i=0; i < n; i++) {
+               ktap_value *o = &f->k[i];
+
+               int t = READ_CHAR(S);
+               switch (t) {
+               case KTAP_TNIL:
+                       setnilvalue(o);
+                       break;
+               case KTAP_TBOOLEAN:
+                       setbvalue(o, READ_CHAR(S));
+                       break;
+               case KTAP_TNUMBER:
+                       /*
+                        * todo: kernel not support fp, check double when
+                        * loading
+                        */
+                       setnvalue(o, READ_NUMBER(S));
+                       break;
+               case KTAP_TSTRING:
+                       setsvalue(o, READ_STRING(S));
+                       break;
+               default:
+                       kp_error(S->ks, "ktap: load_constants: "
+                                       "unknow ktap_value\n");
+                       return -1;
+                       
+               }
+       }
+
+       n = READ_INT(S);
+       f->p = NEW_VECTOR(S, n * sizeof(ktap_proto));
+       f->sizep = n;
+       for (i = 0; i < n; i++)
+               f->p[i] = NULL;
+       for (i = 0; i < n; i++) {
+               f->p[i] = kp_newproto(S->ks);
+               if (load_function(S, f->p[i]))
+                       return -1;
+       }
+
+       return 0;
+}
+
+
+static int load_upvalues(struct load_state *S, ktap_proto *f)
+{
+       int i,n;
+
+       n = READ_INT(S);
+       f->upvalues = NEW_VECTOR(S, n * sizeof(ktap_upvaldesc));
+       f->sizeupvalues = n;
+
+       for (i = 0; i < n; i++)
+               f->upvalues[i].name = NULL;
+
+       for (i = 0; i < n; i++) {
+               f->upvalues[i].instack = READ_BYTE(S);
+               f->upvalues[i].idx = READ_BYTE(S);
+       }
+
+       return 0;
+}
+
+static int load_debuginfo(struct load_state *S, ktap_proto *f)
+{
+       int i,n;
+
+       f->source = READ_STRING(S);
+       n = READ_INT(S);
+       f->sizelineinfo = n;
+       f->lineinfo = NEW_VECTOR(S, n * sizeof(int));
+       READ_VECTOR(S, f->lineinfo, n * sizeof(int));
+       n = READ_INT(S);
+       f->locvars = NEW_VECTOR(S, n * sizeof(struct ktap_locvar));
+       f->sizelocvars = n;
+       for (i = 0; i < n; i++)
+               f->locvars[i].varname = NULL;
+       for (i = 0; i < n; i++) {
+               f->locvars[i].varname = READ_STRING(S);
+               f->locvars[i].startpc = READ_INT(S);
+               f->locvars[i].endpc = READ_INT(S);
+       }
+       n = READ_INT(S);
+       for (i = 0; i < n; i++)
+               f->upvalues[i].name = READ_STRING(S);
+
+       return 0;
+}
+
+static int load_function(struct load_state *S, ktap_proto *f)
+{
+       f->linedefined = READ_INT(S);
+       f->lastlinedefined = READ_INT(S);
+       f->numparams = READ_BYTE(S);
+       f->is_vararg = READ_BYTE(S);
+       f->maxstacksize = READ_BYTE(S);
+       if (load_code(S, f))
+               return -1;
+       if (load_constants(S, f))
+               return -1;
+       if (load_upvalues(S, f))
+               return -1;
+       if (load_debuginfo(S, f))
+               return -1;
+
+       return 0;
+}
+
+
+#define error(S, why) \
+       kp_error(S->ks, "load failed: %s precompiled chunk\n", why)
+
+#define N0     KTAPC_HEADERSIZE
+#define N1     (sizeof(KTAP_SIGNATURE) - sizeof(char))
+#define N2     N1 + 2
+#define N3     N2 + 6
+
+static int load_header(struct load_state *S)
+{
+       u8 h[KTAPC_HEADERSIZE];
+       u8 s[KTAPC_HEADERSIZE];
+
+       kp_header(h);
+       READ_VECTOR(S, s, KTAPC_HEADERSIZE);
+
+       if (memcmp(h, s, N0) == 0)
+               return 0;
+       if (memcmp(h, s, N1) != 0)
+               error(S, "not a");
+       else if (memcmp(h, s, N2) != 0)
+               error(S, "version mismatch in");
+       else if (memcmp(h, s, N3) != 0)
+               error(S, "incompatible");
+       else
+               error(S,"corrupted");
+
+       return -1;
+}
+
+
+static int verify_code(struct load_state *S, ktap_proto *f)
+{
+       /* not support now */
+       return 0;
+}
+
+
+ktap_closure *kp_load(ktap_state *ks, unsigned char *buff)
+{
+       struct load_state S;
+       ktap_closure *cl;
+       ktap_lclosure *f;
+       int ret, i;
+
+       S.ks = ks;
+       S.buff = buff;
+       S.pos = 0;
+
+       ret = load_header(&S);
+       if (ret)
+               return NULL;
+
+       cl = kp_newlclosure(ks, 1);
+       if (!cl)
+               return cl;
+
+       /* put closure on the top, prepare to run with this closure */
+       setcllvalue(ks->top, cl);
+       incr_top(ks);
+
+       cl->l.p = kp_newproto(ks);
+       if (load_function(&S, cl->l.p))
+               return NULL;
+
+       if (cl->l.p->sizeupvalues != 1) {
+               ktap_proto *p = cl->l.p;
+               cl = kp_newlclosure(ks, cl->l.p->sizeupvalues);
+               cl->l.p = p;
+               setcllvalue(ks->top - 1, cl);
+       }
+
+       f = &cl->l;
+       for (i = 0; i < f->nupvalues; i++) {  /* initialize upvalues */
+               ktap_upval *up = kp_newupval(ks);
+               f->upvals[i] = up;
+       }
+
+       /* set global table as 1st upvalue of 'f' */
+       if (f->nupvalues == 1) {
+               ktap_table *reg = hvalue(&G(ks)->registry);
+               const ktap_value *gt = kp_table_getint(reg, KTAP_RIDX_GLOBALS);
+               setobj(f->upvals[0]->v, gt);
+       }
+
+       verify_code(&S, cl->l.p);
+       return cl;
+}
+
diff --git a/drivers/staging/ktap/interpreter/object.c b/drivers/staging/ktap/interpreter/object.c
new file mode 100644 (file)
index 0000000..6538167
--- /dev/null
@@ -0,0 +1,483 @@
+/*
+ * object.c - ktap object generic operation
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef __KERNEL__
+#include "../include/ktap.h"
+#else
+#include "../include/ktap_types.h"
+#endif
+
+#ifdef __KERNEL__
+
+#define KTAP_ALLOC_FLAGS ((GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN) \
+                        & ~__GFP_WAIT)
+
+void *kp_malloc(ktap_state *ks, int size)
+{
+       void *addr;
+
+       /*
+        * Normally we don't want to trace under memory pressure,
+        * so we use a simple rule to handle memory allocation failure:
+        *
+        * retry until allocation success, this will make caller don't need
+        * to handle the unlikely failure case, then ktap exit.
+        *
+        * In this approach, if user find there have memory allocation failure,
+        * user should re-run the ktap script, or fix the memory pressure
+        * issue, or figure out why the script need so many memory.
+        *
+        * Perhaps return pre-allocated stub memory trunk when allocate failed
+        * is a better approch?
+        */
+       addr = kmalloc(size, KTAP_ALLOC_FLAGS);
+       if (unlikely(!addr)) {
+               kp_error(ks, "kmalloc size %d failed, retry again\n", size);
+               printk("ktap kmalloc size %d failed, retry again\n", size);
+               dump_stack();
+               while (1) {
+                       addr = kmalloc(size, KTAP_ALLOC_FLAGS);
+                       if (addr)
+                               break;
+               }
+               kp_printf(ks, "kmalloc retry success after failed, exit\n");
+       }
+
+       return addr;
+}
+
+void kp_free(ktap_state *ks, void *addr)
+{
+       kfree(addr);
+}
+
+void *kp_reallocv(ktap_state *ks, void *addr, int oldsize, int newsize)
+{
+       void *new_addr;
+
+       new_addr = krealloc(addr, newsize, KTAP_ALLOC_FLAGS);
+       if (unlikely(!new_addr)) {
+               kp_error(ks, "krealloc size %d failed, retry again\n", newsize);
+               printk("ktap krealloc size %d failed, retry again\n", newsize);
+               dump_stack();
+               while (1) {
+                       new_addr = krealloc(addr, newsize, KTAP_ALLOC_FLAGS);
+                       if (new_addr)
+                               break;
+               }
+               kp_printf(ks, "krealloc retry success after failed, exit\n");
+       }
+
+       return new_addr;
+}
+
+void *kp_zalloc(ktap_state *ks, int size)
+{
+       void *addr;
+
+       addr = kzalloc(size, KTAP_ALLOC_FLAGS);
+       if (unlikely(!addr)) {
+               kp_error(ks, "kzalloc size %d failed, retry again\n", size);
+               printk("ktap kzalloc size %d failed, retry again\n", size);
+               dump_stack();
+               while (1) {
+                       addr = kzalloc(size, KTAP_ALLOC_FLAGS);
+                       if (addr)
+                               break;
+               }
+               kp_printf(ks, "kzalloc retry success after failed, exit\n");
+       }
+
+       return addr;
+}
+#endif
+
+void kp_obj_dump(ktap_state *ks, const ktap_value *v)
+{
+       switch (ttype(v)) {
+       case KTAP_TNIL:
+               kp_puts(ks, "NIL");
+               break;
+       case KTAP_TNUMBER:
+               kp_printf(ks, "NUMBER %ld", nvalue(v));
+               break;
+       case KTAP_TBOOLEAN:
+               kp_printf(ks, "BOOLEAN %d", bvalue(v));
+               break;
+       case KTAP_TLIGHTUSERDATA:
+               kp_printf(ks, "LIGHTUSERDATA 0x%lx", (unsigned long)pvalue(v));
+               break;
+       case KTAP_TLCF:
+               kp_printf(ks, "LIGHTCFCUNTION 0x%lx", (unsigned long)fvalue(v));
+               break;
+       case KTAP_TSHRSTR:
+       case KTAP_TLNGSTR:
+               kp_printf(ks, "SHRSTR #%s", svalue(v));
+               break;
+       case KTAP_TUSERDATA:
+               kp_printf(ks, "USERDATA 0x%lx", (unsigned long)uvalue(v));
+               break;
+       case KTAP_TTABLE:
+               kp_printf(ks, "TABLE 0x%lx", (unsigned long)hvalue(v));
+               break;
+        default:
+               kp_printf(ks, "GCVALUE 0x%lx", (unsigned long)gcvalue(v));
+               break;
+       }
+}
+
+#ifdef __KERNEL__
+#include <linux/stacktrace.h>
+#include <linux/kallsyms.h>
+
+static void kp_btrace_dump(ktap_state *ks, ktap_btrace *bt)
+{
+       char str[KSYM_SYMBOL_LEN];
+       int i;
+
+       for (i = 0; i < bt->nr_entries; i++) {
+               unsigned long p = bt->entries[i];
+
+               if (p == ULONG_MAX)
+                       break;
+
+               SPRINT_SYMBOL(str, p);
+               kp_printf(ks, "%s\n", str);
+       }
+}
+
+static int kp_btrace_equal(ktap_btrace *bt1, ktap_btrace *bt2)
+{
+       int i;
+
+       if (bt1->nr_entries != bt2->nr_entries)
+               return 0;
+
+       for (i = 0; i < bt1->nr_entries; i++) {
+               if (bt1->entries[i] != bt2->entries[i])
+                       return 0;
+       }
+
+       return 1;
+}
+#endif
+
+void kp_showobj(ktap_state *ks, const ktap_value *v)
+{
+       switch (ttype(v)) {
+       case KTAP_TNIL:
+               kp_puts(ks, "nil");
+               break;
+       case KTAP_TNUMBER:
+               kp_printf(ks, "%ld", nvalue(v));
+               break;
+       case KTAP_TBOOLEAN:
+               kp_puts(ks, (bvalue(v) == 1) ? "true" : "false");
+               break;
+       case KTAP_TLIGHTUSERDATA:
+               kp_printf(ks, "0x%lx", (unsigned long)pvalue(v));
+               break;
+       case KTAP_TLCF:
+               kp_printf(ks, "0x%lx", (unsigned long)fvalue(v));
+               break;
+       case KTAP_TSHRSTR:
+       case KTAP_TLNGSTR:
+               kp_puts(ks, svalue(v));
+               break;
+       case KTAP_TUSERDATA:
+               kp_printf(ks, "0x%lx", (unsigned long)uvalue(v));
+               break;
+       case KTAP_TTABLE:
+               kp_table_dump(ks, hvalue(v));
+               break;
+#ifdef __KERNEL__
+       case KTAP_TEVENT:
+               kp_transport_event_write(ks, evalue(v));
+               break;
+       case KTAP_TBTRACE:
+               kp_btrace_dump(ks, btvalue(v));
+               break;
+       case KTAP_TAGGRTABLE:
+               kp_aggrtable_dump(ks, ahvalue(v));
+               break;
+       case KTAP_TAGGRACCVAL:
+               kp_aggraccval_dump(ks, aggraccvalue(v));
+               break;
+#endif
+        default:
+               kp_error(ks, "print unknown value type: %d\n", ttype(v));
+               break;
+       }
+}
+
+
+/*
+ * equality of ktap values. ks == NULL means raw equality
+ */
+int kp_equalobjv(ktap_state *ks, const ktap_value *t1, const ktap_value *t2)
+{
+       switch (ttype(t1)) {
+       case KTAP_TNIL:
+               return 1;
+       case KTAP_TNUMBER:
+               return nvalue(t1) == nvalue(t2);
+       case KTAP_TBOOLEAN:
+               return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
+       case KTAP_TLIGHTUSERDATA:
+               return pvalue(t1) == pvalue(t2);
+       case KTAP_TLCF:
+               return fvalue(t1) == fvalue(t2);
+       case KTAP_TSHRSTR:
+               return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
+       case KTAP_TLNGSTR:
+               return kp_tstring_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
+       case KTAP_TUSERDATA:
+               if (uvalue(t1) == uvalue(t2))
+                       return 1;
+               else if (ks == NULL)
+                       return 0;
+       case KTAP_TTABLE:
+               if (hvalue(t1) == hvalue(t2))
+                       return 1;
+               else if (ks == NULL)
+                       return 0;
+#ifdef __KERNEL__
+       case KTAP_TBTRACE:
+               return kp_btrace_equal(btvalue(t1), btvalue(t2));
+#endif
+       default:
+               return gcvalue(t1) == gcvalue(t2);
+       }
+
+       return 0;
+}
+
+/*
+ * ktap will not use lua's length operator on table meaning,
+ * also # is not for length operator any more in ktap.
+ *
+ * Quote from lua mannal:
+ * 2.5.5 - The Length Operator
+ *
+ * The length operator is denoted by the unary operator #.
+ * The length of a string is its number of bytes(that is,
+ * the usual meaning of string length when each character is one byte).
+ *
+ * The length of a table t is defined to be any integer index n
+ * such that t[n] is not nil and t[n+1] is nil; moreover, if t[1] is nil,
+ * n can be zero. For a regular array, with non-nil values from 1 to a given n,
+ * its length is exactly that n, the index of its last value. If the array has
+ * "holes" (that is, nil values between other non-nil values), then #t can be
+ * any of the indices that directly precedes a nil value
+ * (that is, it may consider any such nil value as the end of the array).
+ */
+int kp_objlen(ktap_state *ks, const ktap_value *v)
+{
+       switch(v->type) {
+       case KTAP_TTABLE:
+               return kp_table_length(ks, hvalue(v));
+       case KTAP_TSTRING:
+               return rawtsvalue(v)->tsv.len;
+       default:
+               kp_printf(ks, "cannot get length of type %d\n", v->type);
+               return -1;
+       }
+       return 0;
+}
+
+/* need to protect allgc field? */
+ktap_gcobject *kp_newobject(ktap_state *ks, int type, size_t size,
+                           ktap_gcobject **list)
+{
+       ktap_gcobject *o;
+
+       o = kp_malloc(ks, size);
+       if (list == NULL)
+               list = &G(ks)->allgc;
+
+       gch(o)->tt = type;
+       gch(o)->next = *list;
+       *list = o;
+
+       return o;
+}
+
+ktap_upval *kp_newupval(ktap_state *ks)
+{
+       ktap_upval *uv;
+
+       uv = &kp_newobject(ks, KTAP_TUPVAL, sizeof(ktap_upval), NULL)->uv;
+       uv->v = &uv->u.value;
+       setnilvalue(uv->v);
+       return uv;
+}
+
+static ktap_btrace *kp_newbacktrace(ktap_state *ks, ktap_gcobject **list)
+{
+       ktap_btrace *bt;
+
+       bt = &kp_newobject(ks, KTAP_TBTRACE, sizeof(ktap_btrace), list)->bt;
+       return bt;
+}
+
+void kp_objclone(ktap_state *ks, const ktap_value *o, ktap_value *newo,
+                ktap_gcobject **list)
+{
+       if (ttisbtrace(o)) {
+               ktap_btrace *bt;
+               bt = kp_newbacktrace(ks, list);
+               bt->nr_entries = btvalue(o)->nr_entries;
+               memcpy(&bt->entries[0], &btvalue(o)->entries[0],
+                                       sizeof(bt->entries));
+               setbtvalue(newo, bt);
+       } else {
+               kp_error(ks, "cannot clone ktap value type %d\n", ttype(o));
+               setnilvalue(newo);
+       }
+}
+
+ktap_closure *kp_newlclosure(ktap_state *ks, int n)
+{
+       ktap_closure *cl;
+
+       cl = (ktap_closure *)kp_newobject(ks, KTAP_TLCL, sizeof(*cl), NULL);
+       cl->l.p = NULL;
+       cl->l.nupvalues = n;
+       while (n--)
+               cl->l.upvals[n] = NULL;
+
+       return cl;
+}
+
+static void free_proto(ktap_state *ks, ktap_proto *f)
+{
+       kp_free(ks, f->code);
+       kp_free(ks, f->p);
+       kp_free(ks, f->k);
+       kp_free(ks, f->lineinfo);
+       kp_free(ks, f->locvars);
+       kp_free(ks, f->upvalues);
+       kp_free(ks, f);
+}
+
+ktap_proto *kp_newproto(ktap_state *ks)
+{
+       ktap_proto *f;
+       f = (ktap_proto *)kp_newobject(ks, KTAP_TPROTO, sizeof(*f), NULL);
+       f->k = NULL;
+       f->sizek = 0;
+       f->p = NULL;
+       f->sizep = 0;
+       f->code = NULL;
+       f->cache = NULL;
+       f->sizecode = 0;
+       f->lineinfo = NULL;
+       f->sizelineinfo = 0;
+       f->upvalues = NULL;
+       f->sizeupvalues = 0;
+       f->numparams = 0;
+       f->is_vararg = 0;
+       f->maxstacksize = 0;
+       f->locvars = NULL;
+       f->sizelocvars = 0;
+       f->linedefined = 0;
+       f->lastlinedefined = 0;
+       f->source = NULL;
+       return f;
+}
+
+static ktap_udata *newudata(ktap_state *ks, size_t s)
+{
+       ktap_udata *u;
+
+       u = &kp_newobject(ks, KTAP_TUSERDATA, sizeof(ktap_udata) + s, NULL)->u;
+       u->uv.len = s;
+       return u;
+}
+
+void *kp_newuserdata(ktap_state *ks, size_t size)
+{
+       ktap_udata *u;
+
+       u = newudata(ks, size);
+       return u + 1;
+}
+
+void kp_free_gclist(ktap_state *ks, ktap_gcobject *o)
+{
+       while (o) {
+               ktap_gcobject *next;
+
+               next = gch(o)->next;
+               switch (gch(o)->tt) {
+               case KTAP_TTABLE:
+                       kp_table_free(ks, (ktap_table *)o);
+                       break;
+               case KTAP_TPROTO:
+                       free_proto(ks, (ktap_proto *)o);
+                       break;
+#ifdef __KERNEL__
+               case KTAP_TAGGRTABLE:
+                       kp_aggrtable_free(ks, (ktap_aggrtable *)o);
+                       break;
+#endif
+               default:
+                       kp_free(ks, o);
+               }
+               o = next;
+       }
+}
+
+void kp_free_all_gcobject(ktap_state *ks)
+{
+       kp_free_gclist(ks, G(ks)->allgc);
+       G(ks)->allgc = NULL;
+}
+
+/******************************************************************************/
+
+/*
+ * make header for precompiled chunks
+ * if you change the code below be sure to update load_header and FORMAT above
+ * and KTAPC_HEADERSIZE in ktap_types.h
+ */
+void kp_header(u8 *h)
+{
+       int x = 1;
+
+       memcpy(h, KTAP_SIGNATURE, sizeof(KTAP_SIGNATURE) - sizeof(char));
+       h += sizeof(KTAP_SIGNATURE) - sizeof(char);
+       *h++ = (u8)VERSION;
+       *h++ = (u8)FORMAT;
+       *h++ = (u8)(*(char*)&x);                    /* endianness */
+       *h++ = (u8)(sizeof(int));
+       *h++ = (u8)(sizeof(size_t));
+       *h++ = (u8)(sizeof(ktap_instruction));
+       *h++ = (u8)(sizeof(ktap_number));
+       *h++ = (u8)(((ktap_number)0.5) == 0); /* is ktap_number integral? */
+       memcpy(h, KTAPC_TAIL, sizeof(KTAPC_TAIL) - sizeof(char));
+}
+
+
diff --git a/drivers/staging/ktap/interpreter/opcode.c b/drivers/staging/ktap/interpreter/opcode.c
new file mode 100644 (file)
index 0000000..2f44855
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * opcode.c
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "../include/ktap_types.h"
+#include "../include/ktap_opcodes.h"
+
+const char *const ktap_opnames[NUM_OPCODES + 1] = {
+  "MOVE",
+  "LOADK",
+  "LOADKX",
+  "LOADBOOL",
+  "LOADNIL",
+  "GETUPVAL",
+  "GETTABUP",
+  "GETTABLE",
+  "SETTABUP",
+  "SETTABUP_INCR",
+  "SETUPVAL",
+  "SETTABLE",
+  "SETTABLE_INCR",
+  "NEWTABLE",
+  "SELF",
+  "ADD",
+  "SUB",
+  "MUL",
+  "DIV",
+  "MOD",
+  "POW",
+  "UNM",
+  "NOT",
+  "LEN",
+  "CONCAT",
+  "JMP",
+  "EQ",
+  "LT",
+  "LE",
+  "TEST",
+  "TESTSET",
+  "CALL",
+  "TAILCALL",
+  "RETURN",
+  "FORLOOP",
+  "FORPREP",
+  "TFORCALL",
+  "TFORLOOP",
+  "SETLIST",
+  "CLOSURE",
+  "VARARG",
+  "EXTRAARG",
+
+  "EVENT",
+  "EVENT_NAME",
+  "EVENT_ARG", /* arg1, arg2 .. arg9 */
+  NULL
+};
+
+
+#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
+
+const u8 ktap_opmodes[NUM_OPCODES] = {
+/*       T  A    B       C     mode                opcode       */
+  opmode(0, 1, OpArgR, OpArgN, iABC)            /* OP_MOVE */
+ ,opmode(0, 1, OpArgK, OpArgN, iABx)            /* OP_LOADK */
+ ,opmode(0, 1, OpArgN, OpArgN, iABx)            /* OP_LOADKX */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)            /* OP_LOADBOOL */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC)            /* OP_LOADNIL */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC)            /* OP_GETUPVAL */
+ ,opmode(0, 1, OpArgU, OpArgK, iABC)            /* OP_GETTABUP */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC)            /* OP_GETTABLE */
+ ,opmode(0, 0, OpArgK, OpArgK, iABC)            /* OP_SETTABUP */
+ ,opmode(0, 0, OpArgU, OpArgN, iABC)            /* OP_SETUPVAL */
+ ,opmode(0, 0, OpArgK, OpArgK, iABC)            /* OP_SETTABLE */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)            /* OP_NEWTABLE */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC)            /* OP_SELF */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)            /* OP_ADD */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)            /* OP_SUB */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)            /* OP_MUL */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)            /* OP_DIV */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)            /* OP_MOD */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)            /* OP_POW */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)            /* OP_UNM */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)            /* OP_NOT */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)            /* OP_LEN */
+ ,opmode(0, 1, OpArgR, OpArgR, iABC)            /* OP_CONCAT */
+ ,opmode(0, 0, OpArgR, OpArgN, iAsBx)           /* OP_JMP */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC)            /* OP_EQ */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC)            /* OP_LT */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC)            /* OP_LE */
+ ,opmode(1, 0, OpArgN, OpArgU, iABC)            /* OP_TEST */
+ ,opmode(1, 1, OpArgR, OpArgU, iABC)            /* OP_TESTSET */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)            /* OP_CALL */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)            /* OP_TAILCALL */
+ ,opmode(0, 0, OpArgU, OpArgN, iABC)            /* OP_RETURN */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx)           /* OP_FORLOOP */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx)           /* OP_FORPREP */
+ ,opmode(0, 0, OpArgN, OpArgU, iABC)            /* OP_TFORCALL */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx)           /* OP_TFORLOOP */
+ ,opmode(0, 0, OpArgU, OpArgU, iABC)            /* OP_SETLIST */
+ ,opmode(0, 1, OpArgU, OpArgN, iABx)            /* OP_CLOSURE */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC)            /* OP_VARARG */
+ ,opmode(0, 0, OpArgU, OpArgU, iAx)             /* OP_EXTRAARG */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC)            /* OP_EVENT */
+};
+
+
diff --git a/drivers/staging/ktap/interpreter/strfmt.c b/drivers/staging/ktap/interpreter/strfmt.c
new file mode 100644 (file)
index 0000000..2c1e761
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * strfmt.c - printf implementation
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/ctype.h>
+#include <linux/kallsyms.h>
+#include "../include/ktap.h"
+
+/* macro to `unsign' a character */
+#define uchar(c)       ((unsigned char)(c))
+
+#define L_ESC          '%'
+
+/* valid flags in a format specification */
+#define FLAGS  "-+ #0"
+
+#define INTFRMLEN      "ll"
+#define INTFRM_T       long long
+
+/*
+ * maximum size of each format specification (such as '%-099.99d')
+ * (+10 accounts for %99.99x plus margin of error)
+ */
+#define MAX_FORMAT     (sizeof(FLAGS) + sizeof(INTFRMLEN) + 10)
+
+static const char *scanformat(ktap_state *ks, const char *strfrmt, char *form)
+{
+       const char *p = strfrmt;
+       while (*p != '\0' && strchr(FLAGS, *p) != NULL)
+               p++;  /* skip flags */
+
+       if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) {
+               kp_error(ks, "invalid format (repeated flags)\n");
+               return NULL;
+       }
+
+       if (isdigit(uchar(*p)))
+               p++;  /* skip width */
+
+       if (isdigit(uchar(*p)))
+               p++;  /* (2 digits at most) */
+
+       if (*p == '.') {
+               p++;
+               if (isdigit(uchar(*p)))
+                       p++;  /* skip precision */
+               if (isdigit(uchar(*p)))
+                       p++;  /* (2 digits at most) */
+       }
+
+       if (isdigit(uchar(*p))) {
+               kp_error(ks, "invalid format (width or precision too long)\n");
+               return NULL;
+       }
+
+       *(form++) = '%';
+       memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char));
+       form += p - strfrmt + 1;
+       *form = '\0';
+       return p;
+}
+
+
+/*
+ * add length modifier into formats
+ */
+static void addlenmod(char *form, const char *lenmod)
+{
+       size_t l = strlen(form);
+       size_t lm = strlen(lenmod);
+       char spec = form[l - 1];
+
+       strcpy(form + l - 1, lenmod);
+       form[l + lm - 1] = spec;
+       form[l + lm] = '\0';
+}
+
+
+static void ktap_argerror(ktap_state *ks, int narg, const char *extramsg)
+{
+       kp_error(ks, "bad argument #%d: (%s)\n", narg, extramsg);
+}
+
+int kp_strfmt(ktap_state *ks, struct trace_seq *seq)
+{
+       int arg = 1;
+       size_t sfl;
+       ktap_value *arg_fmt = kp_arg(ks, 1);
+       int argnum = kp_arg_nr(ks);
+       const char *strfrmt, *strfrmt_end;
+
+       strfrmt = svalue(arg_fmt);
+       sfl = rawtsvalue(arg_fmt)->tsv.len;
+       strfrmt_end = strfrmt + sfl;
+
+       while (strfrmt < strfrmt_end) {
+               if (*strfrmt != L_ESC)
+                       trace_seq_putc(seq, *strfrmt++);
+               else if (*++strfrmt == L_ESC)
+                       trace_seq_putc(seq, *strfrmt++);
+               else { /* format item */
+                       char form[MAX_FORMAT];
+
+                       if (++arg > argnum) {
+                               ktap_argerror(ks, arg, "no value");
+                               return -1;
+                       }
+
+                       strfrmt = scanformat(ks, strfrmt, form);
+                       switch (*strfrmt++) {
+                       case 'c':
+                               trace_seq_printf(seq, form,
+                                                nvalue(kp_arg(ks, arg)));
+                               break;
+                       case 'd':  case 'i': {
+                               ktap_number n = nvalue(kp_arg(ks, arg));
+                               INTFRM_T ni = (INTFRM_T)n;
+                               addlenmod(form, INTFRMLEN);
+                               trace_seq_printf(seq, form, ni);
+                               break;
+                       }
+                       case 'p': {
+                               char str[KSYM_SYMBOL_LEN];
+                               SPRINT_SYMBOL(str, nvalue(kp_arg(ks, arg)));
+                               trace_seq_puts(seq, str);
+                               break;
+                       }
+                       case 'o':  case 'u':  case 'x':  case 'X': {
+                               ktap_number n = nvalue(kp_arg(ks, arg));
+                               unsigned INTFRM_T ni = (unsigned INTFRM_T)n;
+                               addlenmod(form, INTFRMLEN);
+                               trace_seq_printf(seq, form, ni);
+                               break;
+                       }
+                       case 's': {
+                               ktap_value *v = kp_arg(ks, arg);
+                               const char *s;
+                               size_t l;
+
+                               if (isnil(v)) {
+                                       trace_seq_puts(seq, "nil");
+                                       return 0;
+                               }
+
+                               if (ttisevent(v)) {
+                                       kp_event_tostring(ks, seq);
+                                       return 0;
+                               }
+
+                               s = svalue(v);
+                               l = rawtsvalue(v)->tsv.len;
+                               if (!strchr(form, '.') && l >= 100) {
+                                       /*
+                                        * no precision and string is too long
+                                        * to be formatted;
+                                        * keep original string
+                                        */
+                                       trace_seq_puts(seq, s);
+                                       break;
+                               } else {
+                                       trace_seq_printf(seq, form, s);
+                                       break;
+                               }
+                       }
+                       default: /* also treat cases `pnLlh' */
+                               kp_error(ks, "invalid option " KTAP_QL("%%%c")
+                                            " to " KTAP_QL("format"),
+                                            *(strfrmt - 1));
+                       }
+               }
+       }
+
+       return 0;
+}
+
diff --git a/drivers/staging/ktap/interpreter/table.c b/drivers/staging/ktap/interpreter/table.c
new file mode 100644 (file)
index 0000000..4e83947
--- /dev/null
@@ -0,0 +1,1292 @@
+/*
+ * table.c - ktap table data structure manipulation function
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef __KERNEL__
+#include "../include/ktap.h"
+#include <linux/spinlock.h>
+#include <linux/kallsyms.h>
+#include <linux/sort.h>
+#else
+#include "../include/ktap_types.h"
+
+static inline void sort(void *base, size_t num, size_t size,
+                       int (*cmp_func)(const void *, const void *),
+                       void (*swap_func)(void *, void *, int size))
+{}
+#endif
+
+
+#ifdef __KERNEL__
+#define kp_table_lock_init(t)  \
+       do {    \
+               t->lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;   \
+       } while (0)
+#define kp_table_lock(t)       \
+       do {    \
+               local_irq_save(flags);  \
+               arch_spin_lock(&t->lock);       \
+       } while (0)
+#define kp_table_unlock(t)     \
+       do {    \
+               arch_spin_unlock(&t->lock);     \
+               local_irq_restore(flags);       \
+       } while (0)
+
+#else
+#define kp_table_lock_init(t)
+#define kp_table_lock(t)
+#define kp_table_unlock(t)
+#endif
+
+#define MAXBITS         30
+#define MAXASIZE        (1 << MAXBITS)
+
+
+#define NILCONSTANT     {NULL}, KTAP_TNIL
+const struct ktap_value ktap_nilobjectv = {NILCONSTANT};
+#define ktap_nilobject (&ktap_nilobjectv)
+
+static const ktap_tnode dummynode_ = {
+       {NILCONSTANT}, /* value */
+       {{NILCONSTANT, NULL}}, /* key */
+};
+
+#define gnode(t,i)      (&(t)->node[i])
+#define gkey(n)         (&(n)->i_key.tvk)
+#define gval(n)         (&(n)->i_val)
+#define gnext(n)        ((n)->i_key.nk.next)
+
+#define twoto(x)        (1<<(x))
+#define sizenode(t)    (twoto((t)->lsizenode))
+
+#define hashpow2(t,n)           (gnode(t, lmod((n), sizenode(t))))
+
+#define hashmod(t,n)           (gnode(t, ((n) % ((sizenode(t)-1)|1))))
+
+#define hashstr(t,str)          hashpow2(t, (str)->tsv.hash)
+#define hashboolean(t,p)        hashpow2(t, p)
+#define hashnum(t, n)          hashmod(t, (unsigned int)n)
+#define hashpointer(t,p)       hashmod(t, (unsigned long)(p))
+
+#define dummynode      (&dummynode_)
+#define isdummy(n)     ((n) == dummynode)
+
+static void table_setint(ktap_state *ks, ktap_table *t, int key, ktap_value *v);
+static ktap_value *table_set(ktap_state *ks, ktap_table *t,
+                            const ktap_value *key);
+static void setnodevector(ktap_state *ks, ktap_table *t, int size);
+
+static int ceillog2(unsigned int x)
+{
+       static const u8 log_2[256] = {
+       0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+       6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+       8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+       8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+       8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+       8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+       };
+
+       int l = 0;
+
+       x--;
+       while (x >= 256) { l += 8; x >>= 8; }
+       return l + log_2[x];
+}
+
+
+ktap_table *kp_table_new(ktap_state *ks)
+{
+       ktap_table *t = &kp_newobject(ks, KTAP_TTABLE, sizeof(ktap_table),
+                                     NULL)->h;
+       t->flags = (u8)(~0);
+       t->array = NULL;
+       t->sizearray = 0;
+       t->node = (ktap_tnode *)dummynode;
+       t->gclist = NULL;
+       setnodevector(ks, t, 0);
+
+       kp_table_lock_init(t);
+       return t;
+}
+
+static const ktap_value *table_getint(ktap_table *t, int key)
+{
+       ktap_tnode *n;
+
+       if ((unsigned int)(key - 1) < (unsigned int)t->sizearray)
+               return &t->array[key - 1];
+
+       n = hashnum(t, key);
+       do {
+               if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == key)
+                       return gval(n);
+               else
+                       n = gnext(n);
+       } while (n);
+
+       return ktap_nilobject;
+}
+
+const ktap_value *kp_table_getint(ktap_table *t, int key)
+{
+       const ktap_value *val;
+       unsigned long __maybe_unused flags;
+
+       kp_table_lock(t);
+       val = table_getint(t, key);
+       kp_table_unlock(t);
+
+       return val;
+}
+
+static ktap_tnode *mainposition (const ktap_table *t, const ktap_value *key)
+{
+       switch (ttype(key)) {
+       case KTAP_TNUMBER:
+               return hashnum(t, nvalue(key));
+       case KTAP_TLNGSTR: {
+               ktap_string *s = rawtsvalue(key);
+               if (s->tsv.extra == 0) {  /* no hash? */
+                       s->tsv.hash = kp_string_hash(getstr(s), s->tsv.len,
+                                                    s->tsv.hash);
+                       s->tsv.extra = 1;  /* now it has its hash */
+               }
+               return hashstr(t, rawtsvalue(key));
+               }
+       case KTAP_TSHRSTR:
+               return hashstr(t, rawtsvalue(key));
+       case KTAP_TBOOLEAN:
+               return hashboolean(t, bvalue(key));
+       case KTAP_TLIGHTUSERDATA:
+               return hashpointer(t, pvalue(key));
+       case KTAP_TLCF:
+               return hashpointer(t, fvalue(key));
+       case KTAP_TBTRACE:
+               /* use first entry as hash key, cannot use gcvalue as key */
+               return hashpointer(t, btvalue(key)->entries[0]);
+       default:
+               return hashpointer(t, gcvalue(key));
+       }
+}
+
+static int arrayindex(const ktap_value *key)
+{
+       if (ttisnumber(key)) {
+               ktap_number n = nvalue(key);
+               int k = (int)n;
+               if ((ktap_number)k == n)
+                       return k;
+       }
+
+       /* `key' did not match some condition */
+       return -1;
+}
+
+/*
+ * returns the index of a `key' for table traversals. First goes all
+ * elements in the array part, then elements in the hash part. The
+ * beginning of a traversal is signaled by -1.
+ */
+static int findindex(ktap_state *ks, ktap_table *t, StkId key)
+{
+       int i;
+
+       if (ttisnil(key))
+               return -1;  /* first iteration */
+
+       i = arrayindex(key);
+       if (i > 0 && i <= t->sizearray)  /* is `key' inside array part? */
+               return i - 1;  /* yes; that's the index (corrected to C) */
+       else {
+               ktap_tnode *n = mainposition(t, key);
+               for (;;) {  /* check whether `key' is somewhere in the chain */
+                       /* key may be dead already, but it is ok to use it in `next' */
+                       if (kp_equalobjv(ks, gkey(n), key)) {
+                               i = n - gnode(t, 0);  /* key index in hash table */
+                               /* hash elements are numbered after array ones */
+                               return i + t->sizearray;
+                       } else
+                               n = gnext(n);
+
+                       if (n == NULL)
+                               /* key not found */
+                               kp_error(ks, "invalid table key to next");
+               }
+       }
+}
+
+int kp_table_next(ktap_state *ks, ktap_table *t, StkId key)
+{
+       unsigned long __maybe_unused flags;
+       int i;
+
+       kp_table_lock(t);
+
+       i = findindex(ks, t, key);  /* find original element */
+
+       for (i++; i < t->sizearray; i++) {  /* try first array part */
+               if (!ttisnil(&t->array[i])) {  /* a non-nil value? */
+                       setnvalue(key, i+1);
+                       setobj(key+1, &t->array[i]);
+                       kp_table_unlock(t);
+                       return 1;
+               }
+       }
+
+       for (i -= t->sizearray; i < sizenode(t); i++) {  /* then hash part */
+               if (!ttisnil(gval(gnode(t, i)))) {  /* a non-nil value? */
+                       setobj(key, gkey(gnode(t, i)));
+                       setobj(key+1, gval(gnode(t, i)));
+                       kp_table_unlock(t);
+                       return 1;
+               }
+       }
+
+       kp_table_unlock(t);
+       return 0;  /* no more elements */
+}
+
+
+
+static int computesizes (int nums[], int *narray)
+{
+       int i;
+       int twotoi;  /* 2^i */
+       int a = 0;  /* number of elements smaller than 2^i */
+       int na = 0;  /* number of elements to go to array part */
+       int n = 0;  /* optimal size for array part */
+
+       for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
+               if (nums[i] > 0) {
+                       a += nums[i];
+                       /* more than half elements present? */
+                       if (a > twotoi/2) {
+                               /* optimal size (till now) */
+                               n = twotoi;
+                               /* 
+                                * all elements smaller than n will go to
+                                * array part
+                                */
+                               na = a;
+                       }
+               }
+               if (a == *narray)
+                       break;  /* all elements already counted */
+       }
+       *narray = n;
+       return na;
+}
+
+
+static int countint(const ktap_value *key, int *nums)
+{
+       int k = arrayindex(key);
+
+       /* is `key' an appropriate array index? */
+       if (0 < k && k <= MAXASIZE) {
+               nums[ceillog2(k)]++;  /* count as such */
+               return 1;
+       } else
+               return 0;
+}
+
+
+static int numusearray(const ktap_table *t, int *nums)
+{
+       int lg;
+       int ttlg;  /* 2^lg */
+       int ause = 0;  /* summation of `nums' */
+       int i = 1;  /* count to traverse all array keys */
+
+       /* for each slice */
+       for (lg=0, ttlg=1; lg <= MAXBITS; lg++, ttlg *= 2) {
+               int lc = 0;  /* counter */
+               int lim = ttlg;
+
+               if (lim > t->sizearray) {
+                       lim = t->sizearray;  /* adjust upper limit */
+                       if (i > lim)
+                               break;  /* no more elements to count */
+               }
+
+               /* count elements in range (2^(lg-1), 2^lg] */
+               for (; i <= lim; i++) {
+                       if (!ttisnil(&t->array[i-1]))
+                               lc++;
+               }
+               nums[lg] += lc;
+               ause += lc;
+       }
+       return ause;
+}
+
+static int numusehash(const ktap_table *t, int *nums, int *pnasize)
+{
+       int totaluse = 0;  /* total number of elements */
+       int ause = 0;  /* summation of `nums' */
+       int i = sizenode(t);
+
+       while (i--) {
+               ktap_tnode *n = &t->node[i];
+               if (!isnil(gval(n))) {
+                       ause += countint(gkey(n), nums);
+                       totaluse++;
+               }
+       }
+
+       *pnasize += ause;
+       return totaluse;
+}
+
+
+static void setarrayvector(ktap_state *ks, ktap_table *t, int size)
+{
+       int i;
+
+       kp_realloc(ks, t->array, t->sizearray, size, ktap_value);
+       for (i = t->sizearray; i < size; i++)
+               setnilvalue(&t->array[i]);
+
+       t->sizearray = size;
+}
+
+static void setnodevector(ktap_state *ks, ktap_table *t, int size)
+{
+       int lsize;
+
+       if (size == 0) {  /* no elements to hash part? */
+               t->node = (ktap_tnode *)dummynode;  /* use common `dummynode' */
+               lsize = 0;
+       } else {
+               int i;
+               lsize = ceillog2(size);
+               if (lsize > MAXBITS) {
+                       kp_error(ks, "table overflow\n");
+                       return;
+               }
+
+               size = twoto(lsize);
+               t->node = kp_malloc(ks, size * sizeof(ktap_tnode));
+               for (i = 0; i < size; i++) {
+                       ktap_tnode *n = gnode(t, i);
+                       gnext(n) = NULL;
+                       setnilvalue(gkey(n));
+                       setnilvalue(gval(n));
+               }
+       }
+
+       t->lsizenode = (u8)lsize;
+       t->lastfree = gnode(t, size);  /* all positions are free */
+}
+
+static void table_resize(ktap_state *ks, ktap_table *t, int nasize, int nhsize)
+{
+       int i;
+       int oldasize = t->sizearray;
+       int oldhsize = t->lsizenode;
+       ktap_tnode *nold = t->node;  /* save old hash ... */
+
+#ifdef __KERNEL__
+       kp_verbose_printf(ks, "table resize, nasize: %d, nhsize: %d\n",
+                               nasize, nhsize);
+#endif
+
+       if (nasize > oldasize)  /* array part must grow? */
+               setarrayvector(ks, t, nasize);
+
+       /* create new hash part with appropriate size */
+       setnodevector(ks, t, nhsize);
+
+       if (nasize < oldasize) {  /* array part must shrink? */
+               t->sizearray = nasize;
+               /* re-insert elements from vanishing slice */
+               for (i=nasize; i<oldasize; i++) {
+                       if (!ttisnil(&t->array[i]))
+                               table_setint(ks, t, i + 1, &t->array[i]);
+               }
+
+               /* shrink array */
+               kp_realloc(ks, t->array, oldasize, nasize, ktap_value);
+       }
+
+       /* re-insert elements from hash part */
+       for (i = twoto(oldhsize) - 1; i >= 0; i--) {
+               ktap_tnode *old = nold+i;
+               if (!ttisnil(gval(old))) {
+                       /*
+                        * doesn't need barrier/invalidate cache, as entry was
+                        * already present in the table
+                        */
+                       setobj(table_set(ks, t, gkey(old)), gval(old));
+               }
+       }
+
+       if (!isdummy(nold))
+               kp_free(ks, nold); /* free old array */
+}
+
+void kp_table_resize(ktap_state *ks, ktap_table *t, int nasize, int nhsize)
+{
+       unsigned long __maybe_unused flags;
+
+       kp_table_lock(t);
+       table_resize(ks, t, nasize, nhsize);
+       kp_table_unlock(t);
+}
+
+void kp_table_resizearray(ktap_state *ks, ktap_table *t, int nasize)
+{
+       unsigned long __maybe_unused flags;
+       int nsize;
+
+       kp_table_lock(t);
+
+       nsize = isdummy(t->node) ? 0 : sizenode(t);
+       table_resize(ks, t, nasize, nsize);
+
+       kp_table_unlock(t);
+}
+
+static void rehash(ktap_state *ks, ktap_table *t, const ktap_value *ek)
+{
+       int nasize, na;
+       /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */
+       int nums[MAXBITS+1];
+       int i;
+       int totaluse;
+
+       for (i = 0; i <= MAXBITS; i++)
+               nums[i] = 0;  /* reset counts */
+
+       nasize = numusearray(t, nums);  /* count keys in array part */
+       totaluse = nasize;  /* all those keys are integer keys */
+       totaluse += numusehash(t, nums, &nasize);  /* count keys in hash part */
+       /* count extra key */
+       nasize += countint(ek, nums);
+       totaluse++;
+       /* compute new size for array part */
+       na = computesizes(nums, &nasize);
+       /* resize the table to new computed sizes */
+       table_resize(ks, t, nasize, totaluse - na);
+}
+
+
+static ktap_tnode *getfreepos(ktap_table *t)
+{
+       while (t->lastfree > t->node) {
+               t->lastfree--;
+               if (isnil(gkey(t->lastfree)))
+                       return t->lastfree;
+       }
+       return NULL;  /* could not find a free place */
+}
+
+
+static ktap_value *table_newkey(ktap_state *ks, ktap_table *t,
+                               const ktap_value *key)
+{
+       ktap_tnode *mp;
+       ktap_value newkey;
+
+       mp = mainposition(t, key);
+       if (!isnil(gval(mp)) || isdummy(mp)) {  /* main position is taken? */
+               ktap_tnode *othern;
+               ktap_tnode *n = getfreepos(t);  /* get a free place */
+               if (n == NULL) {  /* cannot find a free place? */
+                       rehash(ks, t, key);  /* grow table */
+                       /* whatever called 'newkey' take care of TM cache and GC barrier */
+                       return table_set(ks, t, key);  /* insert key into grown table */
+               }
+
+               othern = mainposition(t, gkey(mp));
+               if (othern != mp) {  /* is colliding node out of its main position? */
+                       /* yes; move colliding node into free position */
+                       while (gnext(othern) != mp)
+                               othern = gnext(othern);  /* find previous */
+                       gnext(othern) = n;  /* redo the chain with `n' in place of `mp' */
+                       *n = *mp;  /* copy colliding node into free pos. (mp->next also goes) */
+                       gnext(mp) = NULL;  /* now `mp' is free */
+                       setnilvalue(gval(mp));
+               } else {  /* colliding node is in its own main position */
+                       /* new node will go into free position */
+                       gnext(n) = gnext(mp);  /* chain new position */
+                       gnext(mp) = n;
+                       mp = n;
+               }
+       }
+
+       /* special handling for cloneable object, maily for btrace object */
+       if (ttisclone(key))
+               kp_objclone(ks, key, &newkey, &t->gclist);
+       else
+               newkey = *key;
+
+       setobj(gkey(mp), &newkey);
+       return gval(mp);
+}
+
+
+/*
+ * search function for short strings
+ */
+static const ktap_value *table_getstr(ktap_table *t, ktap_string *key)
+{
+       ktap_tnode *n = hashstr(t, key);
+
+       do {  /* check whether `key' is somewhere in the chain */
+               if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)),
+                                                               key))
+                       return gval(n);  /* that's it */
+               else
+                       n = gnext(n);
+       } while (n);
+
+       return ktap_nilobject;
+}
+
+
+/*
+ * main search function
+ */
+static const ktap_value *table_get(ktap_table *t, const ktap_value *key)
+{
+       switch (ttype(key)) {
+       case KTAP_TNIL:
+               return ktap_nilobject;
+       case KTAP_TSHRSTR:
+               return table_getstr(t, rawtsvalue(key));
+       case KTAP_TNUMBER: {
+               ktap_number n = nvalue(key);
+               int k = (int)n;
+               if ((ktap_number)k == nvalue(key)) /* index is int? */
+                       return table_getint(t, k);  /* use specialized version */
+               /* else go through */
+       }
+       default: {
+               ktap_tnode *n = mainposition(t, key);
+               do {  /* check whether `key' is somewhere in the chain */
+                       if (rawequalobj(gkey(n), key))
+                               return gval(n);  /* that's it */
+                       else
+                               n = gnext(n);
+               } while (n);
+
+               return ktap_nilobject;
+       }
+       }
+}
+
+const ktap_value *kp_table_get(ktap_table *t, const ktap_value *key)
+{
+       const ktap_value *val;
+       unsigned long __maybe_unused flags;
+
+       kp_table_lock(t);
+       val = table_get(t, key);
+       kp_table_unlock(t);
+
+       return val;
+}
+
+static ktap_value *table_set(ktap_state *ks, ktap_table *t,
+                            const ktap_value *key)
+{
+       const ktap_value *p = table_get(t, key);
+
+       if (p != ktap_nilobject)
+               return (ktap_value *)p;
+       else
+               return table_newkey(ks, t, key);
+}
+
+void kp_table_setvalue(ktap_state *ks, ktap_table *t,
+                      const ktap_value *key, ktap_value *val)
+{
+       unsigned long __maybe_unused flags;
+
+       if (isnil(key)) {
+               kp_printf(ks, "table index is nil\n");
+               kp_exit(ks);
+               return;
+       }
+
+       kp_table_lock(t);
+       setobj(table_set(ks, t, key), val);
+       kp_table_unlock(t);
+}
+
+static void table_setint(ktap_state *ks, ktap_table *t, int key, ktap_value *v)
+{
+       const ktap_value *p;
+       ktap_value *cell;
+
+       p = table_getint(t, key);
+
+       if (p != ktap_nilobject)
+               cell = (ktap_value *)p;
+       else {
+               ktap_value k;
+               setnvalue(&k, key);
+               cell = table_newkey(ks, t, &k);
+       }
+
+       setobj(cell, v);
+}
+
+void kp_table_setint(ktap_state *ks, ktap_table *t, int key, ktap_value *val)
+{
+       unsigned long __maybe_unused flags;
+
+       kp_table_lock(t);
+       table_setint(ks, t, key, val);
+       kp_table_unlock(t);
+}
+
+void kp_table_atomic_inc(ktap_state *ks, ktap_table *t, ktap_value *key, int n)
+{
+       unsigned long __maybe_unused flags;
+       ktap_value *v;
+
+       if (isnil(key)) {
+               kp_printf(ks, "table index is nil\n");
+               kp_exit(ks);
+               return;
+       }
+
+       kp_table_lock(t);
+
+       v = table_set(ks, t, key);
+       if (isnil(v)) {
+               setnvalue(v, n);
+       } else
+               setnvalue(v, nvalue(v) + n);
+
+       kp_table_unlock(t);
+}
+
+int kp_table_length(ktap_state *ks, ktap_table *t)
+{
+       unsigned long __maybe_unused flags;
+       int i, len = 0;
+
+       kp_table_lock(t);
+
+       for (i = 0; i < t->sizearray; i++) {
+               ktap_value *v = &t->array[i];
+
+               if (isnil(v))
+                       continue;
+               len++;
+       }
+
+       for (i = 0; i < sizenode(t); i++) {
+               ktap_tnode *n = &t->node[i];
+
+               if (isnil(gkey(n)))
+                       continue;
+
+               len++;
+       }
+       
+       kp_table_unlock(t);
+       return len;
+}
+
+void kp_table_free(ktap_state *ks, ktap_table *t)
+{
+       if (t->sizearray > 0)
+               kp_free(ks, t->array);
+       if (!isdummy(t->node))
+               kp_free(ks, t->node);
+
+       kp_free_gclist(ks, t->gclist);
+       kp_free(ks, t);
+}
+
+void kp_table_dump(ktap_state *ks, ktap_table *t)
+{
+       int i, count = 0;
+
+       kp_puts(ks, "{");
+       for (i = 0; i < t->sizearray; i++) {
+               ktap_value *v = &t->array[i];
+
+               if (isnil(v))
+                       continue;
+
+               if (count)
+                       kp_puts(ks, ", ");
+
+               kp_printf(ks, "(%d: ", i + 1);
+               kp_showobj(ks, v);
+               kp_puts(ks, ")");
+               count++;
+       }
+
+       for (i = 0; i < sizenode(t); i++) {
+               ktap_tnode *n = &t->node[i];
+
+               if (isnil(gkey(n)))
+                       continue;
+
+               if (count)
+                       kp_puts(ks, ", ");
+
+               kp_puts(ks, "(");
+               kp_showobj(ks, gkey(n));
+               kp_puts(ks, ": ");
+               kp_showobj(ks, gval(n));
+               kp_puts(ks, ")");
+               count++;
+       }
+       kp_puts(ks, "}");
+}
+
+/*
+ * table-clear only set nil of all elements, not free t->array and nodes.
+ * we assume user will reuse table soon after clear table, so reserve array
+ * and nodes will avoid memory allocation when insert key-value again.
+ */
+void kp_table_clear(ktap_state *ks, ktap_table *t)
+{
+       unsigned long __maybe_unused flags;
+       int i;
+
+       kp_table_lock(t);
+
+       for (i = 0; i < t->sizearray; i++) {
+               ktap_value *v = &t->array[i];
+
+               if (isnil(v))
+                       continue;
+
+               setnilvalue(v);
+       }
+
+       for (i = 0; i < sizenode(t); i++) {
+               ktap_tnode *n = &t->node[i];
+
+               if (isnil(gkey(n)))
+                       continue;
+
+               setnilvalue(gkey(n));
+               setnilvalue(gval(n));
+       }
+
+       kp_table_unlock(t);
+}
+
+#ifdef __KERNEL__
+static void string_convert(char *output, const char *input)
+{
+       if (strlen(input) > 32) {
+               strncpy(output, input, 32-4);
+               memset(output + 32-4, '.', 3);
+       } else
+               memcpy(output, input, strlen(input));
+}
+
+struct table_hist_record {
+       ktap_value key;
+       ktap_value val;
+};
+
+static int hist_record_cmp(const void *r1, const void *r2)
+{
+       const struct table_hist_record *i = r1;
+       const struct table_hist_record *j = r2;
+
+       if ((nvalue(&i->val) == nvalue(&j->val))) {
+               return 0;
+       } else if ((nvalue(&i->val) < nvalue(&j->val))) {
+               return 1;
+       } else
+               return -1;
+}
+
+static int kp_aggracc_read(ktap_aggraccval *acc);
+
+/* histogram: key should be number or string, value must be number */
+static void table_histdump(ktap_state *ks, ktap_table *t, int shownums)
+{
+       struct table_hist_record *thr;
+       unsigned long __maybe_unused flags;
+       char dist_str[40];
+       int i, ratio, total = 0, count = 0, top_num, is_kernel_address = 0;
+       int size, num;
+
+       size = sizeof(*thr) * (t->sizearray + sizenode(t));
+       thr = kp_malloc(ks, size);
+       if (!thr) {
+               kp_error(ks, "Cannot allocate %d of histogram memory", size);
+               return;
+       }
+
+       kp_table_lock(t);
+
+       for (i = 0; i < t->sizearray; i++) {
+               ktap_value *v = &t->array[i];
+
+               if (isnil(v))
+                       continue;
+
+               if (ttisnumber(v))
+                       num = nvalue(v);
+               else if (ttisaggracc(v))
+                       num = kp_aggracc_read(aggraccvalue(v));
+               else {
+                       kp_table_unlock(t);
+                       goto error;
+               }
+
+               setnvalue(&thr[count].key, i + 1);
+               setnvalue(&thr[count].val, num);
+               count++;
+               total += num;
+       }
+
+       for (i = 0; i < sizenode(t); i++) {
+               ktap_tnode *n = &t->node[i];
+               ktap_value *v = gval(n);
+
+               if (isnil(gkey(n)))
+                       continue;
+
+               if (ttisnumber(v))
+                       num = nvalue(v);
+               else if (ttisaggracc(v))
+                       num = kp_aggracc_read(aggraccvalue(v));
+               else {
+                       kp_table_unlock(t);
+                       goto error;
+               }
+
+               setobj(&thr[count].key, gkey(n));
+               setnvalue(&thr[count].val, num);
+               count++;
+               total += num;
+       }
+
+       kp_table_unlock(t);
+
+       sort(thr, count, sizeof(struct table_hist_record),
+            hist_record_cmp, NULL);
+
+       dist_str[sizeof(dist_str) - 1] = '\0';
+
+       /* check the first key is a kernel text symbol or not */
+       if (ttisnumber(&thr[0].key)) {
+               char str[KSYM_SYMBOL_LEN];
+
+               SPRINT_SYMBOL(str, nvalue(&thr[0].key));
+               if (str[0] != '0' || str[1] != 'x')
+                       is_kernel_address = 1;
+       }
+
+       top_num = min(shownums, count);
+       for (i = 0; i < top_num; i++) {
+               ktap_value *key = &thr[i].key;
+               ktap_value *val = &thr[i].val;
+
+               memset(dist_str, ' ', sizeof(dist_str) - 1);
+               ratio = (nvalue(val) * (sizeof(dist_str) - 1)) / total;
+               memset(dist_str, '@', ratio);
+
+               if (ttisstring(key)) {
+                       char buf[32 + 1] = {0};
+
+                       string_convert(buf, svalue(key));
+                       kp_printf(ks, "%32s |%s%-7d\n", buf, dist_str,
+                                     nvalue(val));
+               } else if (ttisnumber(key)) {
+                       char str[KSYM_SYMBOL_LEN];
+                       char buf[32 + 1] = {0};
+
+                       if (is_kernel_address) {
+                               /* suppose it's a symbol, fix it in future */
+                               SPRINT_SYMBOL(str, nvalue(key));
+                               string_convert(buf, str);
+                               kp_printf(ks, "%32s |%s%-7d\n", buf, dist_str,
+                                               nvalue(val));
+                       } else {
+                               kp_printf(ks, "%32d |%s%-7d\n", nvalue(key),
+                                               dist_str, nvalue(val));
+                       }
+               }
+       }
+
+       if (count > shownums)
+               kp_printf(ks, "%32s |\n", "...");
+
+       goto out;
+
+ error:
+       kp_puts(ks, "error: table histogram only handle "
+                       " (key: string/number val: number)\n");
+ out:
+       kp_free(ks, thr);
+}
+
+#define HISTOGRAM_DEFAULT_TOP_NUM      20
+
+#define DISTRIBUTION_STR "------------- Distribution -------------"
+void kp_table_histogram(ktap_state *ks, ktap_table *t)
+{
+       kp_printf(ks, "%32s%s%s\n", "value ", DISTRIBUTION_STR, " count");
+       table_histdump(ks, t, HISTOGRAM_DEFAULT_TOP_NUM);
+}
+
+/*
+ * Aggregation Table
+ */
+
+static ktap_table *table_new2(ktap_state *ks, ktap_gcobject **list)
+{
+       ktap_table *t = &kp_newobject(ks, KTAP_TTABLE, sizeof(ktap_table),
+                                     list)->h;
+       t->flags = (u8)(~0);
+       t->array = NULL;
+       t->sizearray = 0;
+       t->node = (ktap_tnode *)dummynode;
+       t->gclist = NULL;
+       setnodevector(ks, t, 0);
+
+       kp_table_lock_init(t);
+       return t;
+}
+
+static int kp_aggracc_read(ktap_aggraccval *acc)
+{
+       switch (acc->type) {
+       case AGGREGATION_TYPE_COUNT:
+       case AGGREGATION_TYPE_MAX:
+       case AGGREGATION_TYPE_MIN:
+       case AGGREGATION_TYPE_SUM:
+               return acc->val;
+       case AGGREGATION_TYPE_AVG:
+               return acc->val / acc->more;
+       default:
+               return 0;
+       }
+
+}
+
+void kp_aggraccval_dump(ktap_state *ks, ktap_aggraccval *acc)
+{
+       switch (acc->type) {
+       case AGGREGATION_TYPE_COUNT:
+       case AGGREGATION_TYPE_MAX:
+       case AGGREGATION_TYPE_MIN:
+       case AGGREGATION_TYPE_SUM:
+               kp_printf(ks, "%d", acc->val);
+               break;
+       case AGGREGATION_TYPE_AVG:
+               kp_printf(ks, "%d", acc->val / acc->more);
+               break;
+       default:
+               break;
+       }
+}
+
+static void synth_acc(ktap_aggraccval *acc1, ktap_aggraccval *acc2)
+{
+       switch (acc1->type) {
+       case AGGREGATION_TYPE_COUNT:
+               acc2->val += acc1->val;
+               break;
+       case AGGREGATION_TYPE_MAX:
+               acc2->val = max(acc1->val, acc2->val);
+               break;
+       case AGGREGATION_TYPE_MIN:
+               acc2->val = min(acc1->val, acc2->val);
+               break;
+       case AGGREGATION_TYPE_SUM:
+               acc2->val += acc1->val;
+               break;
+       case AGGREGATION_TYPE_AVG:
+               acc2->val += acc1->val;
+               acc2->more += acc1->more;
+               break;
+       default:
+               break;
+       }
+}
+
+static ktap_aggraccval *get_accval(ktap_state *ks, int type,
+                                  ktap_gcobject **list)
+{
+       ktap_aggraccval *acc;
+
+       acc = &kp_newobject(ks, KTAP_TAGGRACCVAL, sizeof(ktap_aggraccval),
+                               list)->acc;
+       acc->type = type;
+       acc->val = 0;
+       acc->more = 0;
+       return acc;
+}
+
+static void synth_accval(ktap_state *ks, ktap_value *o1, ktap_value *o2,
+                        ktap_gcobject **list)
+{
+       ktap_aggraccval *acc;
+
+       if (isnil(o2)) {
+               acc = get_accval(ks, aggraccvalue(o1)->type, list);
+               acc->val = aggraccvalue(o1)->val;
+               acc->more = aggraccvalue(o1)->more;
+               setaggraccvalue(o2, acc);
+               return;
+       }
+
+       synth_acc(aggraccvalue(o1), aggraccvalue(o2));
+}
+
+static void move_table(ktap_state *ks, ktap_table *t1, ktap_table *t2)
+{
+       ktap_value *newv;
+       ktap_value n;
+       int i;
+
+       for (i = 0; i < t1->sizearray; i++) {
+               ktap_value *v = &t1->array[i];
+
+               if (isnil(v))
+                       continue;
+
+               setnvalue(&n, i);
+
+               newv = table_set(ks, t2, &n);
+               synth_accval(ks, v, newv, &t2->gclist);
+       }
+
+       for (i = 0; i < sizenode(t1); i++) {
+               ktap_tnode *node = &t1->node[i];
+
+               if (isnil(gkey(node)))
+                       continue;
+
+               newv = table_set(ks, t2, gkey(node));
+               synth_accval(ks, gval(node), newv, &t2->gclist);
+       }
+}
+
+ktap_table *kp_aggrtable_synthesis(ktap_state *ks, ktap_aggrtable *ah)
+{
+       ktap_table *synth_tbl;
+       int cpu;
+
+       synth_tbl = table_new2(ks, &ah->gclist);
+
+       for_each_possible_cpu(cpu) {
+               ktap_table **t = per_cpu_ptr(ah->pcpu_tbl, cpu);
+               move_table(ks, *t, synth_tbl);
+       }
+
+       return synth_tbl;
+}
+
+void kp_aggrtable_dump(ktap_state *ks, ktap_aggrtable *ah)
+{
+       kp_table_dump(ks, kp_aggrtable_synthesis(ks, ah));
+}
+
+ktap_aggrtable *kp_aggrtable_new(ktap_state *ks)
+{
+       ktap_aggrtable *ah;
+       int cpu;
+
+       ah = &kp_newobject(ks, KTAP_TAGGRTABLE, sizeof(ktap_aggrtable),
+                       NULL)->ah;
+       ah->pcpu_tbl = alloc_percpu(ktap_table *);
+       ah->gclist = NULL;
+
+       for_each_possible_cpu(cpu) {
+               ktap_table **t = per_cpu_ptr(ah->pcpu_tbl, cpu);
+               *t = table_new2(ks, &ah->gclist);
+       }       
+
+       return ah;
+}
+
+void kp_aggrtable_free(ktap_state *ks, ktap_aggrtable *ah)
+{
+       free_percpu(ah->pcpu_tbl);
+       kp_free_gclist(ks, ah->gclist);
+       kp_free(ks, ah);
+}
+
+static
+void handle_aggr_count(ktap_state *ks, ktap_aggrtable *ah, ktap_value *key)
+{
+       ktap_table *t = *__this_cpu_ptr(ah->pcpu_tbl);
+       ktap_value *v = table_set(ks, t, key);
+       ktap_aggraccval *acc;
+
+       if (isnil(v)) {
+               acc = get_accval(ks, AGGREGATION_TYPE_COUNT, &t->gclist);
+               acc->val = 1;
+               setaggraccvalue(v, acc);
+               return;
+       }
+
+       acc = aggraccvalue(v);
+       acc->val += 1;
+}
+
+static 
+void handle_aggr_max(ktap_state *ks, ktap_aggrtable *ah, ktap_value *key)
+{
+       ktap_table *t = *__this_cpu_ptr(ah->pcpu_tbl);
+       ktap_value *v = table_set(ks, t, key);
+       ktap_aggraccval *acc;
+
+       if (isnil(v)) {
+               acc = get_accval(ks, AGGREGATION_TYPE_MAX, &t->gclist);
+               acc->val = ks->aggr_accval;
+               setaggraccvalue(v, acc);
+               return;
+       }
+
+       acc = aggraccvalue(v);
+       acc->val = max(acc->val, ks->aggr_accval);
+}
+
+static 
+void handle_aggr_min(ktap_state *ks, ktap_aggrtable *ah, ktap_value *key)
+{
+       ktap_table *t = *__this_cpu_ptr(ah->pcpu_tbl);
+       ktap_value *v = table_set(ks, t, key);
+       ktap_aggraccval *acc;
+
+       if (isnil(v)) {
+               acc = get_accval(ks, AGGREGATION_TYPE_MIN, &t->gclist);
+               acc->val = ks->aggr_accval;
+               setaggraccvalue(v, acc);
+               return;
+       }
+
+       acc = aggraccvalue(v);
+       acc->val = min(acc->val, ks->aggr_accval);
+}
+
+static 
+void handle_aggr_sum(ktap_state *ks, ktap_aggrtable *ah, ktap_value *key)
+{
+       ktap_table *t = *__this_cpu_ptr(ah->pcpu_tbl);
+       ktap_value *v = table_set(ks, t, key);
+       ktap_aggraccval *acc;
+
+       if (isnil(v)) {
+               acc = get_accval(ks, AGGREGATION_TYPE_SUM, &t->gclist);
+               acc->val = ks->aggr_accval;
+               setaggraccvalue(v, acc);
+               return;
+       }
+
+       acc = aggraccvalue(v);
+       acc->val += ks->aggr_accval;
+}
+
+static 
+void handle_aggr_avg(ktap_state *ks, ktap_aggrtable *ah, ktap_value *key)
+{
+       ktap_table *t = *__this_cpu_ptr(ah->pcpu_tbl);
+       ktap_value *v = table_set(ks, t, key);
+       ktap_aggraccval *acc;
+
+       if (isnil(v)) {
+               acc = get_accval(ks, AGGREGATION_TYPE_AVG, &t->gclist);
+               acc->val = ks->aggr_accval;
+               acc->more = 1;
+               setaggraccvalue(v, acc);
+               return;
+       }
+
+       acc = aggraccvalue(v);
+       acc->val += ks->aggr_accval;
+       acc->more++;
+}
+
+typedef void (*aggr_func_t)(ktap_state *ks, ktap_aggrtable *ah, ktap_value *k);
+static aggr_func_t kp_aggregation_handler[] = {
+       handle_aggr_count,
+       handle_aggr_max,
+       handle_aggr_min,
+       handle_aggr_sum,
+       handle_aggr_avg
+};
+
+void kp_aggrtable_set(ktap_state *ks, ktap_aggrtable *ah,
+                       ktap_value *key, ktap_value *val)
+{
+       if (unlikely(!ttisaggrval(val))) {
+               kp_error(ks, "set invalid value to aggregation table\n");
+               return;
+       }
+
+       kp_aggregation_handler[nvalue(val)](ks, ah, key);
+}
+
+
+void kp_aggrtable_get(ktap_state *ks, ktap_aggrtable *ah, ktap_value *key,
+                     ktap_value *val)
+{
+       ktap_aggraccval acc; /* in stack */
+       const ktap_value *v;
+       int cpu;
+
+       acc.val = -1;
+       acc.more = -1;
+
+       for_each_possible_cpu(cpu) {
+               ktap_table **t = per_cpu_ptr(ah->pcpu_tbl, cpu);
+
+               v = table_get(*t, key);
+               if (isnil(v))
+                       continue;
+
+               if (acc.more == -1) {
+                       acc = *aggraccvalue(v);
+                       continue;
+               }
+
+               synth_acc(aggraccvalue(v), &acc);
+       }
+
+       if (acc.more == -1) {
+               setnilvalue(val);
+       } else {
+               setnvalue(val, kp_aggracc_read(&acc));
+       }
+}
+
+void kp_aggrtable_histogram(ktap_state *ks, ktap_aggrtable *ah)
+{
+       kp_table_histogram(ks, kp_aggrtable_synthesis(ks, ah));
+}
+#endif
diff --git a/drivers/staging/ktap/interpreter/transport.c b/drivers/staging/ktap/interpreter/transport.c
new file mode 100644 (file)
index 0000000..4cd3662
--- /dev/null
@@ -0,0 +1,636 @@
+/*
+ * transport.c - ktap transport functionality
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/ftrace_event.h>
+#include <linux/stacktrace.h>
+#include <linux/clocksource.h>
+#include <asm/uaccess.h>
+#include "../include/ktap.h"
+
+struct ktap_trace_iterator {
+       struct ring_buffer      *buffer;
+       int                     print_timestamp;
+       void                    *private;
+
+       struct trace_iterator   iter;
+};
+
+enum ktap_trace_type {
+       __TRACE_FIRST_TYPE = 0,
+
+       TRACE_FN = 1, /* must be same as ftrace definition in kernel */
+       TRACE_PRINT,
+       TRACE_BPUTS,
+       TRACE_STACK,
+       TRACE_USER_STACK,
+
+       __TRACE_LAST_TYPE,
+};
+
+#define KTAP_TRACE_ITER(iter)  \
+       container_of(iter, struct ktap_trace_iterator, iter)
+
+ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
+{
+       int len;
+       int ret;
+
+       if (!cnt)
+               return 0;
+
+       if (s->len <= s->readpos)
+               return -EBUSY;
+
+       len = s->len - s->readpos;
+       if (cnt > len)
+               cnt = len;
+       ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
+       if (ret == cnt)
+               return -EFAULT;
+
+       cnt -= ret;
+
+       s->readpos += cnt;
+       return cnt;
+}
+
+int trace_seq_puts(struct trace_seq *s, const char *str)
+{
+       int len = strlen(str);
+
+       if (s->full)
+               return 0;
+
+       if (len > ((PAGE_SIZE - 1) - s->len)) {
+               s->full = 1;
+               return 0;
+       }
+
+       memcpy(s->buffer + s->len, str, len);
+       s->len += len;
+
+       return len;
+}
+
+static int trace_empty(struct trace_iterator *iter)
+{
+       struct ktap_trace_iterator *ktap_iter = KTAP_TRACE_ITER(iter);
+       int cpu;
+
+       for_each_online_cpu(cpu) {
+               if (!ring_buffer_empty_cpu(ktap_iter->buffer, cpu))
+                       return 0;
+       }
+
+       return 1;
+}
+
+static void trace_consume(struct trace_iterator *iter)
+{
+       struct ktap_trace_iterator *ktap_iter = KTAP_TRACE_ITER(iter);
+
+       ring_buffer_consume(ktap_iter->buffer, iter->cpu, &iter->ts,
+                           &iter->lost_events);
+}
+
+unsigned long long ns2usecs(cycle_t nsec)
+{
+       nsec += 500;
+       do_div(nsec, 1000);
+       return nsec;
+}
+
+static int trace_print_timestamp(struct trace_iterator *iter)
+{
+       struct trace_seq *s = &iter->seq;
+       unsigned long long t;
+       unsigned long secs, usec_rem;
+
+       t = ns2usecs(iter->ts);
+       usec_rem = do_div(t, USEC_PER_SEC);
+       secs = (unsigned long)t;
+
+       return trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem);
+}
+
+/* todo: export kernel function ftrace_find_event in future, and make faster */
+static struct trace_event *(*ftrace_find_event)(int type);
+
+static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
+{
+       struct ktap_trace_iterator *ktap_iter = KTAP_TRACE_ITER(iter);
+       struct trace_entry *entry = iter->ent;
+       struct trace_event *ev;
+
+       ev = ftrace_find_event(entry->type);
+
+       if (ktap_iter->print_timestamp && !trace_print_timestamp(iter))
+               return TRACE_TYPE_PARTIAL_LINE;
+
+       if (ev) {
+               int ret = ev->funcs->trace(iter, 0, ev);
+
+               /* overwrite '\n' at the ending */
+               iter->seq.buffer[iter->seq.len - 1] = '\0';
+               iter->seq.len--;
+               return ret;
+       }
+
+       return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t print_trace_stack(struct trace_iterator *iter)
+{
+       struct trace_entry *entry = iter->ent;
+       struct stack_trace trace;
+       char str[KSYM_SYMBOL_LEN];
+       int i;
+
+       trace.entries = (unsigned long *)(entry + 1);
+       trace.nr_entries = (iter->ent_size - sizeof(*entry)) /
+                          sizeof(unsigned long);
+
+       if (!trace_seq_puts(&iter->seq, "<stack trace>\n"))
+               return TRACE_TYPE_PARTIAL_LINE;
+
+       for (i = 0; i < trace.nr_entries; i++) {
+               unsigned long p = trace.entries[i];
+
+               if (p == ULONG_MAX)
+                       break;
+
+               sprint_symbol(str, p);
+               if (!trace_seq_printf(&iter->seq, " => %s\n", str))
+                       return TRACE_TYPE_PARTIAL_LINE;
+       }
+
+       return TRACE_TYPE_HANDLED;
+}
+
+struct ktap_ftrace_entry {
+       struct trace_entry entry;
+       unsigned long ip;
+       unsigned long parent_ip;
+};
+
+static enum print_line_t print_trace_fn(struct trace_iterator *iter)
+{
+       struct ktap_trace_iterator *ktap_iter = KTAP_TRACE_ITER(iter);
+       struct ktap_ftrace_entry *field = (struct ktap_ftrace_entry *)iter->ent;
+       char str[KSYM_SYMBOL_LEN];
+
+       if (ktap_iter->print_timestamp && !trace_print_timestamp(iter))
+               return TRACE_TYPE_PARTIAL_LINE;
+
+       sprint_symbol(str, field->ip);
+       if (!trace_seq_puts(&iter->seq, str))
+               return TRACE_TYPE_PARTIAL_LINE;
+
+       if (!trace_seq_puts(&iter->seq, " <- "))
+               return TRACE_TYPE_PARTIAL_LINE;
+
+       sprint_symbol(str, field->parent_ip);
+       if (!trace_seq_puts(&iter->seq, str))
+               return TRACE_TYPE_PARTIAL_LINE;
+
+       return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t print_trace_bputs(struct trace_iterator *iter)
+{
+       if (!trace_seq_puts(&iter->seq,
+                           (const char *)(*(unsigned long *)(iter->ent + 1))))
+               return TRACE_TYPE_PARTIAL_LINE;
+
+       return TRACE_TYPE_HANDLED;
+}
+
+static enum print_line_t print_trace_line(struct trace_iterator *iter)
+{
+       struct trace_entry *entry = iter->ent;
+       char *str = (char *)(entry + 1);
+
+       if (entry->type == TRACE_PRINT) {
+               if (!trace_seq_printf(&iter->seq, "%s", str))
+                       return TRACE_TYPE_PARTIAL_LINE;
+
+               return TRACE_TYPE_HANDLED;
+       }
+
+       if (entry->type == TRACE_BPUTS)
+               return print_trace_bputs(iter);
+
+       if (entry->type == TRACE_STACK)
+               return print_trace_stack(iter);
+
+       if (entry->type == TRACE_FN)
+               return print_trace_fn(iter);
+
+       return print_trace_fmt(iter);
+}
+
+static struct trace_entry *
+peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts,
+               unsigned long *lost_events)
+{
+       struct ktap_trace_iterator *ktap_iter = KTAP_TRACE_ITER(iter);
+       struct ring_buffer_event *event;
+
+       event = ring_buffer_peek(ktap_iter->buffer, cpu, ts, lost_events);
+       if (event) {
+               iter->ent_size = ring_buffer_event_length(event);
+               return ring_buffer_event_data(event);
+       }
+
+       return NULL;
+}
+
+static struct trace_entry *
+__find_next_entry(struct trace_iterator *iter, int *ent_cpu,
+                 unsigned long *missing_events, u64 *ent_ts)
+{
+       struct ktap_trace_iterator *ktap_iter = KTAP_TRACE_ITER(iter);
+       struct ring_buffer *buffer = ktap_iter->buffer;
+       struct trace_entry *ent, *next = NULL;
+       unsigned long lost_events = 0, next_lost = 0;
+       u64 next_ts = 0, ts;
+       int next_cpu = -1;
+       int next_size = 0;
+       int cpu;
+
+       for_each_online_cpu(cpu) {
+               if (ring_buffer_empty_cpu(buffer, cpu))
+                       continue;
+
+               ent = peek_next_entry(iter, cpu, &ts, &lost_events);
+               /*
+                * Pick the entry with the smallest timestamp:
+                */
+               if (ent && (!next || ts < next_ts)) {
+                       next = ent;
+                       next_cpu = cpu;
+                       next_ts = ts;
+                       next_lost = lost_events;
+                       next_size = iter->ent_size;
+               }
+       }
+
+       iter->ent_size = next_size;
+
+       if (ent_cpu)
+               *ent_cpu = next_cpu;
+
+       if (ent_ts)
+               *ent_ts = next_ts;
+
+       if (missing_events)
+               *missing_events = next_lost;
+
+       return next;
+}
+
+/* Find the next real entry, and increment the iterator to the next entry */
+static void *trace_find_next_entry_inc(struct trace_iterator *iter)
+{
+       iter->ent = __find_next_entry(iter, &iter->cpu,
+                                     &iter->lost_events, &iter->ts);
+       if (iter->ent)
+               iter->idx++;
+
+       return iter->ent ? iter : NULL;
+}
+
+static void poll_wait_pipe(void)
+{
+       set_current_state(TASK_INTERRUPTIBLE);
+       /* sleep for 100 msecs, and try again. */
+       schedule_timeout(HZ / 10);
+}
+
+static int tracing_wait_pipe(struct file *filp)
+{
+       struct trace_iterator *iter = filp->private_data;
+       struct ktap_trace_iterator *ktap_iter = KTAP_TRACE_ITER(iter);
+       ktap_state *ks = ktap_iter->private;
+
+       while (trace_empty(iter)) {
+
+               if ((filp->f_flags & O_NONBLOCK)) {
+                       return -EAGAIN;
+               }
+
+               mutex_unlock(&iter->mutex);
+
+               poll_wait_pipe();
+
+               mutex_lock(&iter->mutex);
+
+               if (G(ks)->wait_user && trace_empty(iter))
+                       return -EINTR;
+       }
+
+       return 1;
+}
+
+static ssize_t
+tracing_read_pipe(struct file *filp, char __user *ubuf, size_t cnt,
+                 loff_t *ppos)
+{
+       struct trace_iterator *iter = filp->private_data;
+       ssize_t sret;
+
+       /* return any leftover data */
+       sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
+       if (sret != -EBUSY)
+               return sret;
+       /*
+        * Avoid more than one consumer on a single file descriptor
+        * This is just a matter of traces coherency, the ring buffer itself
+        * is protected.
+        */
+       mutex_lock(&iter->mutex);
+
+waitagain:
+       sret = tracing_wait_pipe(filp);
+       if (sret <= 0)
+               goto out;
+
+       /* stop when tracing is finished */
+       if (trace_empty(iter)) {
+               sret = 0;
+               goto out;
+       }
+
+       if (cnt >= PAGE_SIZE)
+               cnt = PAGE_SIZE - 1;
+
+       /* reset all but tr, trace, and overruns */
+       memset(&iter->seq, 0,
+              sizeof(struct trace_iterator) -
+              offsetof(struct trace_iterator, seq));
+       iter->pos = -1;
+
+       while (trace_find_next_entry_inc(iter) != NULL) {
+               enum print_line_t ret;
+               int len = iter->seq.len;
+
+               ret = print_trace_line(iter);
+               if (ret == TRACE_TYPE_PARTIAL_LINE) {
+                       /* don't print partial lines */
+                       iter->seq.len = len;
+                       break;
+               }
+               if (ret != TRACE_TYPE_NO_CONSUME)
+                       trace_consume(iter);
+
+               if (iter->seq.len >= cnt)
+                       break;
+
+               /*
+                * Setting the full flag means we reached the trace_seq buffer
+                * size and we should leave by partial output condition above.
+                * One of the trace_seq_* functions is not used properly.
+                */
+               WARN_ONCE(iter->seq.full, "full flag set for trace type %d",
+                         iter->ent->type);
+       }
+
+       /* Now copy what we have to the user */
+       sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
+       if (iter->seq.readpos >= iter->seq.len)
+               trace_seq_init(&iter->seq);
+
+       /*
+        * If there was nothing to send to user, in spite of consuming trace
+        * entries, go back to wait for more entries.
+        */
+       if (sret == -EBUSY)
+               goto waitagain;
+
+out:
+       mutex_unlock(&iter->mutex);
+
+       return sret;
+}
+
+static int tracing_open_pipe(struct inode *inode, struct file *filp)
+{
+       struct ktap_trace_iterator *ktap_iter;
+       ktap_state *ks = inode->i_private;
+
+       /* create a buffer to store the information to pass to userspace */
+       ktap_iter = kzalloc(sizeof(*ktap_iter), GFP_KERNEL);
+       if (!ktap_iter)
+               return -ENOMEM;
+
+       ktap_iter->private = ks;
+       ktap_iter->buffer = G(ks)->buffer;
+       ktap_iter->print_timestamp = G(ks)->parm->print_timestamp;
+       mutex_init(&ktap_iter->iter.mutex);
+       filp->private_data = &ktap_iter->iter;
+
+       nonseekable_open(inode, filp);
+
+       return 0;
+}
+
+static int tracing_release_pipe(struct inode *inode, struct file *file)
+{
+       struct trace_iterator *iter = file->private_data;
+       struct ktap_trace_iterator *ktap_iter = KTAP_TRACE_ITER(iter);
+
+       mutex_destroy(&iter->mutex);
+       kfree(ktap_iter);
+       return 0;
+}
+
+static const struct file_operations tracing_pipe_fops = {
+       .open           = tracing_open_pipe,
+       .read           = tracing_read_pipe,
+       .splice_read    = NULL,
+       .release        = tracing_release_pipe,
+       .llseek         = no_llseek,
+};
+
+/*
+ * print_backtrace maybe called from ktap mainthread, so be
+ * care on race with event closure thread.
+ *
+ * preempt disabled in ring_buffer_lock_reserve
+ *
+ * The implementation is similar with funtion __ftrace_trace_stack.
+ */
+void kp_transport_print_backtrace(ktap_state *ks)
+{
+       struct ring_buffer *buffer = G(ks)->buffer;
+       struct ring_buffer_event *event;
+       struct trace_entry *entry;
+       int size;
+
+       size = KTAP_STACK_MAX_ENTRIES * sizeof(unsigned long);
+       event = ring_buffer_lock_reserve(buffer, sizeof(*entry) + size);
+       if (!event) {
+               return;
+       } else {
+               struct stack_trace trace;
+
+               entry = ring_buffer_event_data(event);
+               tracing_generic_entry_update(entry, 0, 0);
+               entry->type = TRACE_STACK;
+
+               trace.nr_entries = 0;
+               trace.skip = 10;
+               trace.max_entries = KTAP_STACK_MAX_ENTRIES;
+               trace.entries = (unsigned long *)(entry + 1);
+               save_stack_trace(&trace);
+
+               ring_buffer_unlock_commit(buffer, event);
+       }
+
+       return;
+}
+
+void kp_transport_event_write(ktap_state *ks, struct ktap_event *e)
+{
+       struct ring_buffer *buffer = G(ks)->buffer;
+       struct ring_buffer_event *event;
+       struct trace_entry *entry;
+
+       event = ring_buffer_lock_reserve(buffer, e->entry_size +
+                                        sizeof(struct ftrace_event_call *));
+       if (!event) {
+               return;
+       } else {
+               entry = ring_buffer_event_data(event);
+
+               memcpy(entry, e->entry, e->entry_size);
+
+               ring_buffer_unlock_commit(buffer, event);
+       }
+}
+
+void kp_transport_write(ktap_state *ks, const void *data, size_t length)
+{
+       struct ring_buffer *buffer = G(ks)->buffer;
+       struct ring_buffer_event *event;
+       struct trace_entry *entry;
+       int size;
+
+       size = sizeof(struct trace_entry) + length;
+
+       event = ring_buffer_lock_reserve(buffer, size);
+       if (!event) {
+               return;
+       } else {
+               entry = ring_buffer_event_data(event);
+
+               tracing_generic_entry_update(entry, 0, 0);
+               entry->type = TRACE_PRINT;
+               memcpy(entry + 1, data, length);
+
+               ring_buffer_unlock_commit(buffer, event);
+       }
+}
+
+/* general print function */
+void kp_printf(ktap_state *ks, const char *fmt, ...)
+{
+       char buff[1024];
+       va_list args;
+       int len;
+
+       va_start(args, fmt);
+       len = vscnprintf(buff, 1024, fmt, args);
+       va_end(args);
+
+       buff[len] = '\0';
+       kp_transport_write(ks, buff, len + 1);
+}
+
+void __kp_puts(ktap_state *ks, const char *str)
+{
+       kp_transport_write(ks, str, strlen(str) + 1);
+}
+
+void __kp_bputs(ktap_state *ks, const char *str)
+{
+       struct ring_buffer *buffer = G(ks)->buffer;
+       struct ring_buffer_event *event;
+       struct trace_entry *entry;
+       int size;
+
+       size = sizeof(struct trace_entry) + sizeof(unsigned long *);
+
+       event = ring_buffer_lock_reserve(buffer, size);
+       if (!event) {
+               return;
+       } else {
+               entry = ring_buffer_event_data(event);
+
+               tracing_generic_entry_update(entry, 0, 0);
+               entry->type = TRACE_BPUTS;
+               *(unsigned long *)(entry + 1) = (unsigned long)str;
+
+               ring_buffer_unlock_commit(buffer, event);
+       }
+}
+
+void kp_transport_exit(ktap_state *ks)
+{
+       ring_buffer_free(G(ks)->buffer);
+       debugfs_remove(G(ks)->trace_pipe_dentry);
+}
+
+#define TRACE_BUF_SIZE_DEFAULT 1441792UL /* 16384 * 88 (sizeof(entry)) */
+
+int kp_transport_init(ktap_state *ks, struct dentry *dir)
+{
+       struct ring_buffer *buffer;
+       struct dentry *dentry;
+       char filename[32] = {0};
+
+       ftrace_find_event = (void *)kallsyms_lookup_name("ftrace_find_event");
+       if (!ftrace_find_event) {
+               printk("ktap: cannot lookup ftrace_find_event in kallsyms\n");
+               return -EINVAL;
+       }
+
+       buffer = ring_buffer_alloc(TRACE_BUF_SIZE_DEFAULT, RB_FL_OVERWRITE);
+       if (!buffer)
+               return -ENOMEM;
+
+       sprintf(filename, "trace_pipe_%d", (int)task_tgid_vnr(current));
+
+       dentry = debugfs_create_file(filename, 0444, dir,
+                                    ks, &tracing_pipe_fops);
+       if (!dentry) {
+               pr_err("ktapvm: cannot create trace_pipe file in debugfs\n");
+               ring_buffer_free(buffer);
+               return -1;
+       }
+
+       G(ks)->buffer = buffer;
+       G(ks)->trace_pipe_dentry = dentry;
+
+       return 0;
+}
+
diff --git a/drivers/staging/ktap/interpreter/tstring.c b/drivers/staging/ktap/interpreter/tstring.c
new file mode 100644 (file)
index 0000000..ce4c88d
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * tstring.c - ktap tstring data struction manipulation function
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef __KERNEL__
+#include "../include/ktap.h"
+#else
+#include "../include/ktap_types.h"
+#endif
+
+#define STRING_MAXSHORTLEN     40
+
+int kp_tstring_cmp(const ktap_string *ls, const ktap_string *rs)
+{
+       const char *l = getstr(ls);
+       size_t ll = ls->tsv.len;
+       const char *r = getstr(rs);
+       size_t lr = rs->tsv.len;
+
+       for (;;) {
+               int temp = strcmp(l, r);
+               if (temp != 0)
+                       return temp;
+               else {
+                       /* strings are equal up to a `\0' */
+
+                       /* index of first `\0' in both strings */
+                       size_t len = strlen(l);
+
+                       /* r is finished? */
+                       if (len == lr)
+                               return (len == ll) ? 0 : 1;
+                       else if (len == ll)  /* l is finished? */
+                               return -1;
+
+                       /*
+                        * both strings longer than `len';
+                        * go on comparing (after the `\0')
+                        */
+                       len++;
+                       l += len; ll -= len; r += len; lr -= len;
+               }
+       }
+}
+
+/*
+ * equality for long strings
+ */
+int kp_tstring_eqlngstr(ktap_string *a, ktap_string *b)
+{
+       size_t len = a->tsv.len;
+
+       return (a == b) || ((len == b->tsv.len) &&
+               (memcmp(getstr(a), getstr(b), len) == 0));
+}
+
+/*
+ * equality for strings
+ */
+int kp_tstring_eqstr(ktap_string *a, ktap_string *b)
+{
+       return (a->tsv.tt == b->tsv.tt) &&
+              (a->tsv.tt == KTAP_TSHRSTR ? eqshrstr(a, b) :
+                               kp_tstring_eqlngstr(a, b));
+}
+
+#define STRING_HASHLIMIT       5
+unsigned int kp_string_hash(const char *str, size_t l, unsigned int seed)
+{
+       unsigned int h = seed ^ l;
+       size_t l1;
+       size_t step = (l >> STRING_HASHLIMIT) + 1;
+
+       for (l1 = l; l1 >= step; l1 -= step)
+               h = h ^ ((h<<5) + (h>>2) + (u8)(str[l1 - 1]));
+
+       return h;
+}
+
+
+/*
+ * resizes the string table
+ */
+void kp_tstring_resize(ktap_state *ks, int newsize)
+{
+       int i;
+       ktap_stringtable *tb = &G(ks)->strt;
+
+       if (newsize > tb->size) {
+               kp_realloc(ks, tb->hash, tb->size, newsize, ktap_gcobject *);
+
+       for (i = tb->size; i < newsize; i++)
+               tb->hash[i] = NULL;
+       }
+
+       /* rehash */
+       for (i = 0; i < tb->size; i++) {
+               ktap_gcobject *p = tb->hash[i];
+               tb->hash[i] = NULL;
+
+               while (p) {
+                       ktap_gcobject *next = gch(p)->next;
+                       unsigned int h = lmod(gco2ts(p)->hash, newsize);
+
+                       gch(p)->next = tb->hash[h];
+                       tb->hash[h] = p;
+                       p = next;
+               }
+       }
+
+       if (newsize < tb->size) {
+               /* shrinking slice must be empty */
+               kp_realloc(ks, tb->hash, tb->size, newsize, ktap_gcobject *);
+       }
+
+       tb->size = newsize;
+}
+
+/*
+ * creates a new string object
+ */
+static ktap_string *createstrobj(ktap_state *ks, const char *str, size_t l,
+                                int tag, unsigned int h, ktap_gcobject **list)
+{
+       ktap_string *ts;
+       size_t totalsize;  /* total size of TString object */
+
+       totalsize = sizeof(ktap_string) + ((l + 1) * sizeof(char));
+       ts = &kp_newobject(ks, tag, totalsize, list)->ts;
+       ts->tsv.len = l;
+       ts->tsv.hash = h;
+       ts->tsv.extra = 0;
+       memcpy(ts + 1, str, l * sizeof(char));
+       ((char *)(ts + 1))[l] = '\0';  /* ending 0 */
+       return ts;
+}
+
+/*
+ * creates a new short string, inserting it into string table
+ */
+static ktap_string *newshrstr(ktap_state *ks, const char *str, size_t l,
+                         unsigned int h)
+{
+       ktap_gcobject **list;
+       ktap_stringtable *tb = &G(ks)->strt;
+       ktap_string *s;
+
+       if (tb->nuse >= (int)tb->size)
+               kp_tstring_resize(ks, tb->size * 2);  /* too crowded */
+
+       list = &tb->hash[lmod(h, tb->size)];
+       s = createstrobj(ks, str, l, KTAP_TSHRSTR, h, list);
+       tb->nuse++;
+       return s;
+}
+
+#ifdef __KERNEL__
+static arch_spinlock_t tstring_lock =
+               (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;
+#endif
+
+/*
+ * checks whether short string exists and reuses it or creates a new one
+ */
+static ktap_string *internshrstr(ktap_state *ks, const char *str, size_t l)
+{
+       ktap_gcobject *o;
+       ktap_global_state *g = G(ks);
+       ktap_string *ts;
+       unsigned int h = kp_string_hash(str, l, g->seed);
+       unsigned long __maybe_unused flags;
+
+#ifdef __KERNEL__
+       local_irq_save(flags);
+       arch_spin_lock(&tstring_lock);
+#endif
+
+       for (o = g->strt.hash[lmod(h, g->strt.size)]; o != NULL;
+            o = gch(o)->next) {
+               ts = rawgco2ts(o);
+
+               if (h == ts->tsv.hash && ts->tsv.len == l &&
+                  (memcmp(str, getstr(ts), l * sizeof(char)) == 0))
+                       goto out;
+       }
+
+       ts = newshrstr(ks, str, l, h);  /* not found; create a new string */
+
+ out:
+#ifdef __KERNEL__
+       arch_spin_unlock(&tstring_lock);
+       local_irq_restore(flags);
+#endif
+       return ts;
+}
+
+
+/*
+ * new string (with explicit length)
+ */
+ktap_string *kp_tstring_newlstr(ktap_state *ks, const char *str, size_t l)
+{
+       /* short string? */
+       if (l <= STRING_MAXSHORTLEN)
+               return internshrstr(ks, str, l);
+       else
+               return createstrobj(ks, str, l, KTAP_TLNGSTR, G(ks)->seed,
+                                   NULL);
+}
+
+ktap_string *kp_tstring_newlstr_local(ktap_state *ks, const char *str, size_t l)
+{
+       return createstrobj(ks, str, l, KTAP_TLNGSTR, G(ks)->seed,
+                           &ks->gclist);
+}
+
+/*
+ * new zero-terminated string
+ */
+ktap_string *kp_tstring_new(ktap_state *ks, const char *str)
+{
+       return kp_tstring_newlstr(ks, str, strlen(str));
+}
+
+ktap_string *kp_tstring_new_local(ktap_state *ks, const char *str)
+{
+       return createstrobj(ks, str, strlen(str), KTAP_TLNGSTR, G(ks)->seed,
+                           &ks->gclist);
+}
+
+void kp_tstring_freeall(ktap_state *ks)
+{
+       ktap_global_state *g = G(ks);
+       int h;
+
+       for (h = 0; h < g->strt.size; h++) {
+               ktap_gcobject *o, *next;
+               o = g->strt.hash[h];
+               while (o) {
+                       next = gch(o)->next;
+                       kp_free(ks, o);
+                       o = next;
+               }
+               g->strt.hash[h] = NULL;
+       }
+
+       kp_free(ks, g->strt.hash);
+}
+
+/* todo: dump long string, strt table only contain short string */
+void kp_tstring_dump(ktap_state *ks)
+{
+       ktap_gcobject *o;
+       ktap_global_state *g = G(ks);
+       int h;
+
+       kp_printf(ks, "tstring dump: strt size: %d, nuse: %d\n", g->strt.size,
+                                                                g->strt.nuse);
+       for (h = 0; h < g->strt.size; h++) {
+               for (o = g->strt.hash[h]; o != NULL; o = gch(o)->next) {
+                       ktap_string *ts = rawgco2ts(o);
+                       kp_printf(ks, "%s [%d]\n", getstr(ts), (int)ts->tsv.len);
+               }
+       }
+}
+
diff --git a/drivers/staging/ktap/interpreter/vm.c b/drivers/staging/ktap/interpreter/vm.c
new file mode 100644 (file)
index 0000000..bc7b951
--- /dev/null
@@ -0,0 +1,1369 @@
+/*
+ * vm.c - ktap script virtual machine in Linux kernel
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/ftrace_event.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include "../include/ktap.h"
+
+#define KTAP_MINSTACK 20
+
+/* todo: enlarge maxstack for big system like 64-bit */
+#define KTAP_MAXSTACK           15000
+
+#define KTAP_STACK_SIZE (BASIC_STACK_SIZE * sizeof(ktap_value))
+
+#define CIST_KTAP      (1 << 0) /* call is running a ktap function */
+#define CIST_REENTRY   (1 << 2)
+
+#define isktapfunc(ci) ((ci)->callstatus & CIST_KTAP)
+
+static void ktap_concat(ktap_state *ks, int start, int end)
+{
+       int i, len = 0;
+       StkId top = ks->ci->u.l.base;
+       ktap_string *ts;
+       char *ptr, *buffer;
+
+       for (i = start; i <= end; i++) {
+               if (!ttisstring(top + i)) {
+                       kp_error(ks, "cannot concat non-string\n");
+                       setnilvalue(top + start);
+                       return;
+               }
+
+               len += rawtsvalue(top + i)->tsv.len;
+       }
+
+       if (len >= KTAP_PERCPU_BUFFER_SIZE) {
+               kp_error(ks, "Error: too long string concatenation\n");
+               return;
+       }
+
+       preempt_disable_notrace();
+
+       buffer = kp_percpu_data(KTAP_PERCPU_DATA_BUFFER);
+       ptr = buffer;
+
+       for (i = start; i <= end; i++) {
+               int len = rawtsvalue(top + i)->tsv.len;
+               strncpy(ptr, svalue(top + i), len);
+               ptr += len;
+       }
+       ts = kp_tstring_newlstr(ks, buffer, len);
+       setsvalue(top + start, ts);
+
+       preempt_enable_notrace();
+}
+
+/* todo: compare l == r if both is tstring type? */
+static int lessthan(ktap_state *ks, const ktap_value *l, const ktap_value *r)
+{
+       if (ttisnumber(l) && ttisnumber(r))
+               return NUMLT(nvalue(l), nvalue(r));
+       else if (ttisstring(l) && ttisstring(r))
+               return kp_tstring_cmp(rawtsvalue(l), rawtsvalue(r)) < 0;
+
+       return 0;
+}
+
+static int lessequal(ktap_state *ks, const ktap_value *l, const ktap_value *r)
+{
+       if (ttisnumber(l) && ttisnumber(r))
+               return NUMLE(nvalue(l), nvalue(r));
+       else if (ttisstring(l) && ttisstring(r))
+               return kp_tstring_cmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
+
+       return 0;
+}
+
+static int fb2int (int x)
+{
+       int e = (x >> 3) & 0x1f;
+       if (e == 0)
+               return x;
+       else
+               return ((x & 7) + 8) << (e - 1);
+}
+
+static const ktap_value *ktap_tonumber(const ktap_value *obj, ktap_value *n)
+{
+       if (ttisnumber(obj))
+               return obj;
+
+       return NULL;
+}
+
+static ktap_upval *findupval(ktap_state *ks, StkId level)
+{
+       ktap_global_state *g = G(ks);
+       ktap_gcobject **pp = &ks->openupval;
+       ktap_upval *p;
+       ktap_upval *uv;
+
+       while (*pp != NULL && (p = gco2uv(*pp))->v >= level) {
+               if (p->v == level) {  /* found a corresponding upvalue? */
+                       return p;
+               }
+               pp = &p->next;
+       }
+
+       /* not found: create a new one */
+       uv = &kp_newobject(ks, KTAP_TUPVAL, sizeof(ktap_upval), pp)->uv;
+       uv->v = level;  /* current value lives in the stack */
+       uv->u.l.prev = &g->uvhead;  /* double link it in `uvhead' list */
+       uv->u.l.next = g->uvhead.u.l.next;
+       uv->u.l.next->u.l.prev = uv;
+       g->uvhead.u.l.next = uv;
+       return uv;
+}
+
+/* todo: implement this*/
+static void function_close (ktap_state *ks, StkId level)
+{
+}
+
+/* create a new closure */
+static void pushclosure(ktap_state *ks, ktap_proto *p, ktap_upval **encup,
+                       StkId base, StkId ra)
+{
+       int nup = p->sizeupvalues;
+       ktap_upvaldesc *uv = p->upvalues;
+       int i;
+       ktap_closure *ncl = kp_newlclosure(ks, nup);
+
+       ncl->l.p = p;
+       setcllvalue(ra, ncl);  /* anchor new closure in stack */
+
+       /* fill in its upvalues */
+       for (i = 0; i < nup; i++) {
+               if (uv[i].instack) {
+                       /* upvalue refers to local variable? */
+                       ncl->l.upvals[i] = findupval(ks, base + uv[i].idx);
+               } else {
+                       /* get upvalue from enclosing function */
+                       ncl->l.upvals[i] = encup[uv[i].idx];
+               }
+       }
+       //p->cache = ncl;  /* save it on cache for reuse */
+}
+
+static void gettable(ktap_state *ks, const ktap_value *t, ktap_value *key,
+                    StkId val)
+{
+       if (ttistable(t)) {
+               setobj(val, kp_table_get(hvalue(t), key));
+       } else if (ttisaggrtable(t)) {
+               kp_aggrtable_get(ks, ahvalue(t), key, val);
+       } else {
+               kp_error(ks, "get key from non-table\n");
+       }
+}
+
+static void settable(ktap_state *ks, const ktap_value *t, ktap_value *key,
+                    StkId val)
+{
+       if (ttistable(t)) {
+               kp_table_setvalue(ks, hvalue(t), key, val);
+       } else if (ttisaggrtable(t)) {
+               kp_aggrtable_set(ks, ahvalue(t), key, val);
+       } else {
+               kp_error(ks, "set key to non-table\n");
+       }
+}
+
+static void settable_incr(ktap_state *ks, const ktap_value *t, ktap_value *key,
+                         StkId val)
+{
+       if (unlikely(!ttistable(t))) {
+               kp_error(ks, "use += operator for non-table\n");
+               return;
+       }
+
+       if (unlikely(!ttisnumber(val))) {
+               kp_error(ks, "use non-number to += operator\n");
+               return;
+       }
+
+       kp_table_atomic_inc(ks, hvalue(t), key, nvalue(val));
+}
+
+
+static void growstack(ktap_state *ks, int n)
+{
+       ktap_value *oldstack;
+       int lim;
+       ktap_callinfo *ci;
+       ktap_gcobject *up;
+       int size = ks->stacksize;
+       int needed = (int)(ks->top - ks->stack) + n;
+       int newsize = 2 * size;
+
+       if (newsize > KTAP_MAXSTACK)
+               newsize = KTAP_MAXSTACK;
+
+       if (newsize < needed)
+               newsize = needed;
+
+       if (newsize > KTAP_MAXSTACK) {  /* stack overflow? */
+               kp_error(ks, "stack overflow\n");
+               return;
+       }
+
+       /* realloc stack */
+       oldstack = ks->stack;
+       lim = ks->stacksize;
+       kp_realloc(ks, ks->stack, ks->stacksize, newsize, ktap_value);
+
+       for (; lim < newsize; lim++)
+               setnilvalue(ks->stack + lim);
+       ks->stacksize = newsize;
+       ks->stack_last = ks->stack + newsize;
+
+       /* correct stack */
+       ks->top = (ks->top - oldstack) + ks->stack;
+       for (up = ks->openupval; up != NULL; up = up->gch.next)
+               gco2uv(up)->v = (gco2uv(up)->v - oldstack) + ks->stack;
+
+       for (ci = ks->ci; ci != NULL; ci = ci->prev) {
+               ci->top = (ci->top - oldstack) + ks->stack;
+               ci->func = (ci->func - oldstack) + ks->stack;
+               if (isktapfunc(ci))
+                       ci->u.l.base = (ci->u.l.base - oldstack) + ks->stack;
+       }
+       
+}
+
+static inline void checkstack(ktap_state *ks, int n)
+{
+       if (ks->stack_last - ks->top <= n)
+               growstack(ks, n);
+}
+
+static StkId adjust_varargs(ktap_state *ks, ktap_proto *p, int actual)
+{
+       int i;
+       int nfixargs = p->numparams;
+       StkId base, fixed;
+
+       /* move fixed parameters to final position */
+       fixed = ks->top - actual;  /* first fixed argument */
+       base = ks->top;  /* final position of first argument */
+
+       for (i=0; i < nfixargs; i++) {
+               setobj(ks->top++, fixed + i);
+               setnilvalue(fixed + i);
+       }
+
+       return base;
+}
+
+static int poscall(ktap_state *ks, StkId first_result)
+{
+       ktap_callinfo *ci;
+       StkId res;
+       int wanted, i;
+
+       ci = ks->ci;
+
+       res = ci->func;
+       wanted = ci->nresults;
+
+       ks->ci = ci = ci->prev;
+
+       for (i = wanted; i != 0 && first_result < ks->top; i--)
+               setobj(res++, first_result++);
+
+       while(i-- > 0)
+               setnilvalue(res++);
+
+       ks->top = res;
+
+       return (wanted - (-1));
+}
+
+static ktap_callinfo *extend_ci(ktap_state *ks)
+{
+       ktap_callinfo *ci;
+
+       ci = kp_malloc(ks, sizeof(ktap_callinfo));
+       ks->ci->next = ci;
+       ci->prev = ks->ci;
+       ci->next = NULL;
+
+       return ci;
+}
+
+static void free_ci(ktap_state *ks)
+{
+       ktap_callinfo *ci = ks->ci;
+       ktap_callinfo *next;
+
+       if (!ci)
+               return;
+
+       next = ci->next;
+       ci->next = NULL;
+       while ((ci = next) != NULL) {
+               next = ci->next;
+               kp_free(ks, ci);
+       }
+}
+
+#define next_ci(ks) (ks->ci = ks->ci->next ? ks->ci->next : extend_ci(ks))
+#define savestack(ks, p)       ((char *)(p) - (char *)ks->stack)
+#define restorestack(ks, n)    ((ktap_value *)((char *)ks->stack + (n)))
+
+static int precall(ktap_state *ks, StkId func, int nresults)
+{
+       ktap_cfunction f;
+       ktap_callinfo *ci;
+       ktap_proto *p;
+       StkId base;
+       ptrdiff_t funcr = savestack(ks, func);
+       int n;
+
+       switch (ttype(func)) {
+       case KTAP_TLCF: /* light C function */
+               f = fvalue(func);
+               goto CFUNC;
+       case KTAP_TCCL: /* C closure */
+               f = clcvalue(func)->f;
+ CFUNC:
+               checkstack(ks, KTAP_MINSTACK);
+               ci = next_ci(ks);
+               ci->nresults = nresults;
+               ci->func = restorestack(ks, funcr);
+               ci->top = ks->top + KTAP_MINSTACK;
+               ci->callstatus = 0;
+               n = (*f)(ks);
+               poscall(ks, ks->top - n);
+               return 1;
+       case KTAP_TLCL: 
+               p = CLVALUE(func)->p;
+               checkstack(ks, p->maxstacksize);
+               func = restorestack(ks, funcr);
+               n = (int)(ks->top - func) - 1; /* number of real arguments */
+
+               /* complete missing arguments */
+               for (; n < p->numparams; n++)
+                       setnilvalue(ks->top++);
+
+               base = (!p->is_vararg) ? func + 1 : adjust_varargs(ks, p, n);
+               ci = next_ci(ks);
+               ci->nresults = nresults;
+               ci->func = func;
+               ci->u.l.base = base;
+               ci->top = base + p->maxstacksize;
+               ci->u.l.savedpc = p->code; /* starting point */
+               ci->callstatus = CIST_KTAP;
+               ks->top = ci->top;
+               return 0;
+       default:
+               kp_error(ks, "attempt to call nil function\n");
+       }
+
+       return 0;
+}
+
+#define RA(i)   (base+GETARG_A(i))
+#define RB(i)   (base+GETARG_B(i))
+#define ISK(x)  ((x) & BITRK)
+#define RC(i)   base+GETARG_C(i)
+#define RKB(i) \
+        ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)
+#define RKC(i)  \
+        ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)
+
+#define dojump(ci,i,e) { \
+       ci->u.l.savedpc += GETARG_sBx(i) + e; }
+#define donextjump(ci)  { instr = *ci->u.l.savedpc; dojump(ci, instr, 1); }
+
+#define arith_op(ks, op) { \
+       ktap_value *rb = RKB(instr); \
+       ktap_value *rc = RKC(instr); \
+       if (ttisnumber(rb) && ttisnumber(rc)) { \
+               ktap_number nb = nvalue(rb), nc = nvalue(rc); \
+               setnvalue(ra, op(nb, nc)); \
+       } else {        \
+               kp_puts(ks, "Error: Cannot make arith operation\n");    \
+               return; \
+       } }
+
+static ktap_value *cfunction_cache_get(ktap_state *ks, int index);
+
+static void ktap_execute(ktap_state *ks)
+{
+       int exec_count = 0;
+       ktap_callinfo *ci;
+       ktap_lclosure *cl;
+       ktap_value *k;
+       unsigned int instr, opcode;
+       StkId base; /* stack pointer */
+       StkId ra; /* register pointer */
+       int res, nresults; /* temp varible */
+
+       ci = ks->ci;
+
+ newframe:
+       cl = CLVALUE(ci->func);
+       k = cl->p->k;
+       base = ci->u.l.base;
+
+ mainloop:
+       /* main loop of interpreter */
+
+       /* dead loop detaction */
+       if (exec_count++ == kp_max_exec_count) {
+               if (G(ks)->mainthread != ks) {
+                       kp_error(ks, "non-mainthread executed instructions "
+                                    "exceed max limit(%d)\n",
+                                       kp_max_exec_count);
+                       return;
+               }
+
+               cond_resched();
+               if (signal_pending(current)) {
+                       flush_signals(current);
+                       return;
+               }
+               exec_count = 0;
+       }
+
+       instr = *(ci->u.l.savedpc++);
+       opcode = GET_OPCODE(instr);
+
+       /* ra is target register */
+       ra = RA(instr);
+
+       switch (opcode) {
+       case OP_MOVE:
+               setobj(ra, base + GETARG_B(instr));
+               break;
+       case OP_LOADK:
+               setobj(ra, k + GETARG_Bx(instr));
+               break;
+       case OP_LOADKX:
+               setobj(ra, k + GETARG_Ax(*ci->u.l.savedpc++));
+               break;
+       case OP_LOADBOOL:
+               setbvalue(ra, GETARG_B(instr));
+               if (GETARG_C(instr))
+                       ci->u.l.savedpc++;
+               break;
+       case OP_LOADNIL: {
+               int b = GETARG_B(instr);
+               do {
+                       setnilvalue(ra++);
+               } while (b--);
+               break;
+               }
+       case OP_GETUPVAL: {
+               int b = GETARG_B(instr);
+               setobj(ra, cl->upvals[b]->v);
+               break;
+               }
+       case OP_GETTABUP: {
+               int b = GETARG_B(instr);
+               gettable(ks, cl->upvals[b]->v, RKC(instr), ra);
+               base = ci->u.l.base;
+               break;
+               }
+       case OP_GETTABLE:
+               gettable(ks, RB(instr), RKC(instr), ra);
+               base = ci->u.l.base;
+               break;
+       case OP_SETTABUP: {
+               int a = GETARG_A(instr);
+               settable(ks, cl->upvals[a]->v, RKB(instr), RKC(instr));
+               base = ci->u.l.base;
+               break;
+               }
+       case OP_SETTABUP_INCR: {
+               int a = GETARG_A(instr);
+               settable_incr(ks, cl->upvals[a]->v, RKB(instr), RKC(instr));
+               base = ci->u.l.base;
+               break;
+               }
+       case OP_SETUPVAL: {
+               ktap_upval *uv = cl->upvals[GETARG_B(instr)];
+               setobj(uv->v, ra);
+               break;
+               }
+       case OP_SETTABLE:
+               settable(ks, ra, RKB(instr), RKC(instr));
+               base = ci->u.l.base;
+               break;
+       case OP_SETTABLE_INCR:
+               settable_incr(ks, ra, RKB(instr), RKC(instr));
+               base = ci->u.l.base;
+               break;
+       case OP_NEWTABLE: {
+               int b = GETARG_B(instr);
+               int c = GETARG_C(instr);
+               ktap_table *t = kp_table_new(ks);
+               sethvalue(ra, t);
+               if (b != 0 || c != 0)
+                       kp_table_resize(ks, t, fb2int(b), fb2int(c));
+               break;
+               }
+       case OP_SELF: {
+               StkId rb = RB(instr);
+               setobj(ra+1, rb);
+               gettable(ks, rb, RKC(instr), ra);
+               base = ci->u.l.base;
+               break;
+               }
+       case OP_ADD:
+               arith_op(ks, NUMADD);
+               break;
+       case OP_SUB:
+               arith_op(ks, NUMSUB);
+               break;
+       case OP_MUL:
+               arith_op(ks, NUMMUL);
+               break;
+       case OP_DIV:
+               /* divide 0 checking */
+               if (!nvalue(RKC(instr))) {
+                       kp_error(ks, "divide 0 arith operation\n");
+                       return;
+               }
+               arith_op(ks, NUMDIV);
+               break;
+       case OP_MOD:
+               /* divide 0 checking */
+               if (!nvalue(RKC(instr))) {
+                       kp_error(ks, "mod 0 arith operation\n");
+                       return;
+               }
+               arith_op(ks, NUMMOD);
+               break;
+       case OP_POW:
+               kp_error(ks, "ktap don't support pow arith in kernel\n");
+               return;
+       case OP_UNM: {
+               ktap_value *rb = RB(instr);
+               if (ttisnumber(rb)) {
+                       ktap_number nb = nvalue(rb);
+                       setnvalue(ra, NUMUNM(nb));
+               }
+               break;
+               }
+       case OP_NOT:
+               res = isfalse(RB(instr));
+               setbvalue(ra, res);
+               break;
+       case OP_LEN: {
+               int len = kp_objlen(ks, RB(instr));
+               if (len < 0)
+                       return;
+               setnvalue(ra, len);
+               break;
+               }
+       case OP_CONCAT: {
+               int b = GETARG_B(instr);
+               int c = GETARG_C(instr);
+               ktap_concat(ks, b, c);
+               break;
+               }
+       case OP_JMP:
+               dojump(ci, instr, 0);
+               break;
+       case OP_EQ: {
+               ktap_value *rb = RKB(instr);
+               ktap_value *rc = RKC(instr);
+               if ((int)equalobj(ks, rb, rc) != GETARG_A(instr))
+                       ci->u.l.savedpc++;
+               else
+                       donextjump(ci);
+
+               base = ci->u.l.base;
+               break;
+               }
+       case OP_LT:
+               if (lessthan(ks, RKB(instr), RKC(instr)) != GETARG_A(instr))
+                       ci->u.l.savedpc++;
+               else
+                       donextjump(ci);
+               base = ci->u.l.base;
+               break;
+       case OP_LE:
+               if (lessequal(ks, RKB(instr), RKC(instr)) != GETARG_A(instr))
+                       ci->u.l.savedpc++;
+               else
+                       donextjump(ci);
+               base = ci->u.l.base;
+               break;
+       case OP_TEST:
+               if (GETARG_C(instr) ? isfalse(ra) : !isfalse(ra))
+                       ci->u.l.savedpc++;
+               else
+                       donextjump(ci);
+               break;
+       case OP_TESTSET: {
+               ktap_value *rb = RB(instr);
+               if (GETARG_C(instr) ? isfalse(rb) : !isfalse(rb))
+                       ci->u.l.savedpc++;
+               else {
+                       setobj(ra, rb);
+                       donextjump(ci);
+               }
+               break;
+               }
+       case OP_CALL: {
+               int b = GETARG_B(instr);
+               int ret;
+
+               nresults = GETARG_C(instr) - 1;
+
+               if (b != 0)
+                       ks->top = ra + b;
+
+               ret = precall(ks, ra, nresults);
+               if (ret) { /* C function */
+                       if (nresults >= 0)
+                               ks->top = ci->top;
+                       base = ci->u.l.base;
+                       break;
+               } else { /* ktap function */
+                       ci = ks->ci;
+                       /* this flag is used for return time, see OP_RETURN */
+                       ci->callstatus |= CIST_REENTRY;
+                       goto newframe;
+               }
+               break;
+               }
+       case OP_TAILCALL: {
+               int b = GETARG_B(instr);
+
+               if (b != 0)
+                       ks->top = ra+b;
+               if (precall(ks, ra, -1))  /* C function? */
+                       base = ci->u.l.base;
+               else {
+                       int aux;
+
+                       /* 
+                        * tail call: put called frame (n) in place of
+                        * caller one (o)
+                        */
+                       ktap_callinfo *nci = ks->ci;  /* called frame */
+                       ktap_callinfo *oci = nci->prev;  /* caller frame */
+                       StkId nfunc = nci->func;  /* called function */
+                       StkId ofunc = oci->func;  /* caller function */
+                       /* last stack slot filled by 'precall' */
+                       StkId lim = nci->u.l.base +
+                                   CLVALUE(nfunc)->p->numparams;
+
+                       /* close all upvalues from previous call */
+                       if (cl->p->sizep > 0)
+                               function_close(ks, oci->u.l.base);
+
+                       /* move new frame into old one */
+                       for (aux = 0; nfunc + aux < lim; aux++)
+                               setobj(ofunc + aux, nfunc + aux);
+                       /* correct base */
+                       oci->u.l.base = ofunc + (nci->u.l.base - nfunc);
+                       /* correct top */
+                       oci->top = ks->top = ofunc + (ks->top - nfunc);
+                       oci->u.l.savedpc = nci->u.l.savedpc;
+                       /* remove new frame */
+                       ci = ks->ci = oci;
+                       /* restart ktap_execute over new ktap function */
+                       goto newframe;
+               }
+               break;
+               }
+       case OP_RETURN: {
+               int b = GETARG_B(instr);
+               if (b != 0)
+                       ks->top = ra+b-1;
+               if (cl->p->sizep > 0)
+                       function_close(ks, base);
+               b = poscall(ks, ra);
+
+               /* if it's called from external invocation, just return */
+               if (!(ci->callstatus & CIST_REENTRY))
+                       return;
+
+               ci = ks->ci;
+               if (b)
+                       ks->top = ci->top;
+               goto newframe;
+               }
+       case OP_FORLOOP: {
+               ktap_number step = nvalue(ra+2);
+               /* increment index */
+               ktap_number idx = NUMADD(nvalue(ra), step);
+               ktap_number limit = nvalue(ra+1);
+               if (NUMLT(0, step) ? NUMLE(idx, limit) : NUMLE(limit, idx)) {
+                       ci->u.l.savedpc += GETARG_sBx(instr);  /* jump back */
+                       setnvalue(ra, idx);  /* update internal index... */
+                       setnvalue(ra+3, idx);  /* ...and external index */
+               }
+               break;
+               }
+       case OP_FORPREP: {
+               const ktap_value *init = ra;
+               const ktap_value *plimit = ra + 1;
+               const ktap_value *pstep = ra + 2;
+
+               if (!ktap_tonumber(init, ra)) {
+                       kp_error(ks, KTAP_QL("for")
+                                " initial value must be a number\n");
+                       return;
+               } else if (!ktap_tonumber(plimit, ra + 1)) {
+                       kp_error(ks, KTAP_QL("for")
+                                " limit must be a number\n");
+                       return;
+               } else if (!ktap_tonumber(pstep, ra + 2)) {
+                       kp_error(ks, KTAP_QL("for") " step must be a number\n");
+                       return;
+               }
+
+               setnvalue(ra, NUMSUB(nvalue(ra), nvalue(pstep)));
+               ci->u.l.savedpc += GETARG_sBx(instr);
+               break;
+               }
+       case OP_TFORCALL: {
+               StkId cb = ra + 3;  /* call base */
+               setobj(cb + 2, ra + 2);
+               setobj(cb + 1, ra + 1);
+               setobj(cb, ra);
+               ks->top = cb + 3;  /* func. + 2 args (state and index) */
+               kp_call(ks, cb, GETARG_C(instr));
+               base = ci->u.l.base;
+               ks->top = ci->top;
+               instr = *(ci->u.l.savedpc++);  /* go to next instruction */
+               ra = RA(instr);
+               }
+               /*go through */
+       case OP_TFORLOOP:
+               if (!ttisnil(ra + 1)) {  /* continue loop? */
+                       setobj(ra, ra + 1);  /* save control variable */
+                       ci->u.l.savedpc += GETARG_sBx(instr);  /* jump back */
+               }
+               break;
+       case OP_SETLIST: {
+               int n = GETARG_B(instr);
+               int c = GETARG_C(instr);
+               int last;
+               ktap_table *h;
+
+               if (n == 0)
+                       n = (int)(ks->top - ra) - 1;
+               if (c == 0)
+                       c = GETARG_Ax(*ci->u.l.savedpc++);
+
+               h = hvalue(ra);
+               last = ((c - 1) * LFIELDS_PER_FLUSH) + n;
+               if (last > h->sizearray)  /* needs more space? */
+                       kp_table_resizearray(ks, h, last);
+
+               for (; n > 0; n--) {
+                       ktap_value *val = ra+n;
+                       kp_table_setint(ks, h, last--, val);
+               }
+               /* correct top (in case of previous open call) */
+               ks->top = ci->top;
+               break;
+               }
+       case OP_CLOSURE: {
+               /* need to use closure cache? (multithread contention issue)*/
+               ktap_proto *p = cl->p->p[GETARG_Bx(instr)];
+               pushclosure(ks, p, cl->upvals, base, ra);
+               break;
+               }
+       case OP_VARARG: {
+               int b = GETARG_B(instr) - 1;
+               int j;
+               int n = (int)(base - ci->func) - cl->p->numparams - 1;
+               if (b < 0) {  /* B == 0? */
+                       b = n;  /* get all var. arguments */
+                       checkstack(ks, n);
+                       /* previous call may change the stack */
+                       ra = RA(instr);
+                       ks->top = ra + n;
+               }
+               for (j = 0; j < b; j++) {
+                       if (j < n) {
+                               setobj(ra + j, base - n + j);
+                       } else
+                               setnilvalue(ra + j);
+               }
+               break;
+               }
+       case OP_EXTRAARG:
+               return;
+
+       case OP_EVENT: {
+               struct ktap_event *e = ks->current_event;
+
+               if (unlikely(!e)) {
+                       kp_error(ks, "invalid event context\n");
+                       return;
+               }
+               setevalue(ra, e);
+               break;
+               }
+
+       case OP_EVENTNAME: {
+               struct ktap_event *e = ks->current_event;
+
+               if (unlikely(!e)) {
+                       kp_error(ks, "invalid event context\n");
+                       return;
+               }
+               setsvalue(ra, kp_tstring_new(ks, e->call->name));
+               break;
+               }
+       case OP_EVENTARG:
+               if (unlikely(!ks->current_event)) {
+                       kp_error(ks, "invalid event context\n");
+                       return;
+               }
+
+               kp_event_getarg(ks, ra, GETARG_B(instr));               
+               break;
+       case OP_LOAD_GLOBAL: {
+               ktap_value *cfunc = cfunction_cache_get(ks, GETARG_C(instr));
+               setobj(ra, cfunc);
+               }
+               break;
+
+       case OP_EXIT:
+               return;
+       }
+
+       goto mainloop;
+}
+
+void kp_call(ktap_state *ks, StkId func, int nresults)
+{
+       if (!precall(ks, func, nresults))
+               ktap_execute(ks);
+}
+
+static int cfunction_cache_getindex(ktap_state *ks, ktap_value *fname);
+
+/*
+ * This function must be called before all code loaded.
+ */
+void kp_optimize_code(ktap_state *ks, int level, ktap_proto *f)
+{
+       int i;
+
+       for (i = 0; i < f->sizecode; i++) {
+               int instr = f->code[i];
+               ktap_value *k = f->k;
+
+               if (GET_OPCODE(instr) == OP_GETTABUP) {
+                       if ((GETARG_B(instr) == 0) && ISK(GETARG_C(instr))) {
+                               ktap_value *field = k + INDEXK(GETARG_C(instr));
+                               if (ttype(field) == KTAP_TSTRING) {
+                                       int index = cfunction_cache_getindex(ks,
+                                                                       field);
+                                       if (index == -1)
+                                               break;
+
+                                       SET_OPCODE(instr, OP_LOAD_GLOBAL);
+                                       SETARG_C(instr, index);
+                                       f->code[i] = instr;
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       /* continue optimize sub functions */
+       for (i = 0; i < f->sizep; i++)
+               kp_optimize_code(ks, level + 1, f->p[i]);
+}
+
+static ktap_value *cfunction_cache_get(ktap_state *ks, int index)
+{
+       return &G(ks)->cfunction_tbl[index];
+}
+
+static int cfunction_cache_getindex(ktap_state *ks, ktap_value *fname)
+{
+       const ktap_value *gt = kp_table_getint(hvalue(&G(ks)->registry),
+                               KTAP_RIDX_GLOBALS);
+       const ktap_value *cfunc;
+       int nr, i;
+
+       nr = G(ks)->nr_builtin_cfunction;
+       cfunc = kp_table_get(hvalue(gt), fname);
+
+       for (i = 0; i < nr; i++) {
+               if (rawequalobj(&G(ks)->cfunction_tbl[i], cfunc))
+                       return i;
+       }
+
+       return -1;
+}
+
+static void cfunction_cache_add(ktap_state *ks, ktap_value *func)
+{
+       int nr = G(ks)->nr_builtin_cfunction;
+       setobj(&G(ks)->cfunction_tbl[nr], func);
+       G(ks)->nr_builtin_cfunction++;
+}
+
+static void cfunction_cache_exit(ktap_state *ks)
+{
+       kp_free(ks, G(ks)->cfunction_tbl);
+}
+
+static int cfunction_cache_init(ktap_state *ks)
+{
+       G(ks)->cfunction_tbl = kp_zalloc(ks, sizeof(ktap_value) * 128);
+       if (!G(ks)->cfunction_tbl)
+               return -ENOMEM;
+
+       return 0;
+}
+
+/* function for register library */
+void kp_register_lib(ktap_state *ks, const char *libname, const ktap_Reg *funcs)
+{
+       int i;
+       ktap_table *target_tbl;
+       const ktap_value *gt = kp_table_getint(hvalue(&G(ks)->registry),
+                                              KTAP_RIDX_GLOBALS);
+
+       /* lib is null when register baselib function */
+       if (libname == NULL)
+               target_tbl = hvalue(gt);
+       else {
+               ktap_value key, val;
+
+               target_tbl = kp_table_new(ks);
+               kp_table_resize(ks, target_tbl, 0,
+                               sizeof(*funcs) / sizeof(ktap_Reg));
+
+               setsvalue(&key, kp_tstring_new(ks, libname));
+               sethvalue(&val, target_tbl);
+               kp_table_setvalue(ks, hvalue(gt), &key, &val);
+       }
+
+       for (i = 0; funcs[i].name != NULL; i++) {
+               ktap_value func_name, cl;
+
+               setsvalue(&func_name, kp_tstring_new(ks, funcs[i].name));
+               setfvalue(&cl, funcs[i].func);
+               kp_table_setvalue(ks, target_tbl, &func_name, &cl);
+
+               cfunction_cache_add(ks, &cl);
+       }
+}
+
+#define BASIC_STACK_SIZE        (2 * KTAP_MINSTACK)
+
+static void kp_init_registry(ktap_state *ks)
+{
+       ktap_value mt;
+       ktap_table *registry = kp_table_new(ks);
+
+       sethvalue(&G(ks)->registry, registry);
+       kp_table_resize(ks, registry, KTAP_RIDX_LAST, 0);
+       setthvalue(ks, &mt, ks);
+       kp_table_setint(ks, registry, KTAP_RIDX_MAINTHREAD, &mt);
+       sethvalue(&mt, kp_table_new(ks));
+       kp_table_setint(ks, registry, KTAP_RIDX_GLOBALS, &mt);
+}
+
+static int kp_init_arguments(ktap_state *ks, int argc, char __user **user_argv)
+{
+       const ktap_value *gt = kp_table_getint(hvalue(&G(ks)->registry),
+                          KTAP_RIDX_GLOBALS);
+       ktap_table *global_tbl = hvalue(gt);
+       ktap_table *arg_tbl = kp_table_new(ks);
+       ktap_value arg_tblval;
+       ktap_value arg_tsval;
+       char **argv;
+       int i, ret;
+       
+       setsvalue(&arg_tsval, kp_tstring_new(ks, "arg"));
+       sethvalue(&arg_tblval, arg_tbl);
+       kp_table_setvalue(ks, global_tbl, &arg_tsval, &arg_tblval);
+
+       if (!argc)
+               return 0;
+
+       if (argc > 1024)
+               return -EINVAL;
+
+       argv = kzalloc(argc * sizeof(char *), GFP_KERNEL);
+       if (!argv)
+               return -ENOMEM;
+
+       ret = copy_from_user(argv, user_argv, argc * sizeof(char *));
+       if (ret < 0) {
+               kfree(argv);
+               return -EFAULT;
+       }
+
+       kp_table_resize(ks, arg_tbl, argc, 1);
+
+       ret = 0;
+       for (i = 0; i < argc; i++) {
+               ktap_value val;
+               char __user *ustr = argv[i];
+               char * kstr;
+               int len;
+               int res;
+
+               len = strlen_user(ustr);
+               if (len > 0x1000) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               kstr = kmalloc(len + 1, GFP_KERNEL);
+               if (!kstr) {
+                       ret = -ENOMEM;
+                       break;
+               }
+
+               if (strncpy_from_user(kstr, ustr, len) < 0) {
+                       ret = -EFAULT;
+                       break;
+               }
+
+               kstr[len] = '\0';
+
+               if (!kstrtoint(kstr, 10, &res)) {
+                       setnvalue(&val, res);
+               } else
+                       setsvalue(&val, kp_tstring_new(ks, kstr));
+
+               kp_table_setint(ks, arg_tbl, i, &val);
+
+               kfree(kstr);
+       }
+
+       kfree(argv);
+       return ret;
+}
+
+DEFINE_PER_CPU(int, kp_recursion_context[PERF_NR_CONTEXTS]);
+
+/* todo: make this per-session aware */
+static void __percpu *kp_pcpu_data[KTAP_PERCPU_DATA_MAX][PERF_NR_CONTEXTS];
+
+void *kp_percpu_data(int type)
+{
+       return this_cpu_ptr(kp_pcpu_data[type][trace_get_context_bit()]);
+}
+
+static void free_kp_percpu_data(void)
+{
+       int i, j;
+
+       for (i = 0; i < KTAP_PERCPU_DATA_MAX; i++) {
+               for (j = 0; j < PERF_NR_CONTEXTS; j++) {
+                       free_percpu(kp_pcpu_data[i][j]);
+                       kp_pcpu_data[i][j] = NULL;
+               }
+       }
+}
+
+static int alloc_kp_percpu_data(void)
+{
+       int data_size[KTAP_PERCPU_DATA_MAX] = {
+               sizeof(ktap_state), KTAP_STACK_SIZE, KTAP_PERCPU_BUFFER_SIZE,
+               KTAP_PERCPU_BUFFER_SIZE, sizeof(ktap_btrace)};
+       int i, j;
+
+       for (i = 0; i < KTAP_PERCPU_DATA_MAX; i++) {
+               for (j = 0; j < PERF_NR_CONTEXTS; j++) {
+                       void __percpu *data = __alloc_percpu(data_size[i],
+                                                            __alignof__(char));
+                       if (!data)
+                               goto fail;
+                       kp_pcpu_data[i][j] = data;
+               }
+       }
+
+       return 0;
+
+ fail:
+       free_kp_percpu_data();
+       return -ENOMEM;
+}
+
+static void kp_init_state(ktap_state *ks)
+{
+       ktap_callinfo *ci;
+       int i;
+
+       ks->stacksize = BASIC_STACK_SIZE;
+
+       for (i = 0; i < BASIC_STACK_SIZE; i++)
+               setnilvalue(ks->stack + i);
+
+       ks->top = ks->stack;
+       ks->stack_last = ks->stack + ks->stacksize;
+
+       ci = &ks->baseci;
+       ci->callstatus = 0;
+       ci->func = ks->top;
+       setnilvalue(ks->top++);
+       ci->top = ks->top + KTAP_MINSTACK;
+       ks->ci = ci;
+}
+
+static void free_all_ci(ktap_state *ks)
+{
+       int cpu;
+
+       for_each_possible_cpu(cpu) {
+               ktap_state *ks;
+               int j;
+
+               for (j = 0; j < PERF_NR_CONTEXTS; j++) {
+                       if (!kp_pcpu_data[KTAP_PERCPU_DATA_STATE][j])
+                               break;
+
+                       ks = per_cpu_ptr(kp_pcpu_data[KTAP_PERCPU_DATA_STATE][j], cpu);
+                       if (!ks)
+                               break;
+
+                       free_ci(ks);
+               }
+       }
+
+       free_ci(ks);
+}
+
+void kp_exitthread(ktap_state *ks)
+{
+       /* free local allocation objects, like annotate strings */
+       kp_free_gclist(ks, ks->gclist);
+}
+
+ktap_state *kp_newthread(ktap_state *mainthread)
+{
+       ktap_state *ks;
+
+       ks = kp_percpu_data(KTAP_PERCPU_DATA_STATE);
+       ks->stack = kp_percpu_data(KTAP_PERCPU_DATA_STACK);
+       G(ks) = G(mainthread);
+       ks->gclist = NULL;
+       kp_init_state(ks);
+       return ks;
+}
+
+/*
+ * wait ktapio thread read all content in ring buffer.
+ *
+ * Here we use stupid approach to sync with ktapio thread,
+ * note that we cannot use semaphore/completion/other sync method,
+ * because ktapio thread could be killed by SIG_KILL in anytime, there
+ * have no safe way to up semaphore or wake waitqueue before thread exit.
+ *
+ * we also cannot use waitqueue of current->signal->wait_chldexit to sync
+ * exit, becasue mainthread and ktapio thread are in same thread group.
+ *
+ * Also ktap mainthread must wait ktapio thread exit, otherwise ktapio
+ * thread will oops when access ktap structure.
+ */
+static void wait_user_completion(ktap_state *ks)
+{
+       struct task_struct *tsk = G(ks)->task;
+       G(ks)->wait_user = 1;
+
+       while (1) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               /* sleep for 100 msecs, and try again. */
+               schedule_timeout(HZ / 10);
+
+               if (get_nr_threads(tsk) == 1)
+                       break;
+       }
+}
+
+/* kp_wait: used for mainthread waiting for exit */
+static void kp_wait(ktap_state *ks)
+{
+       struct task_struct *task = G(ks)->trace_task;
+
+       if (G(ks)->exit)
+               return;
+
+       ks->stop = 0;
+
+       /* tell workload process to start executing */
+       if (G(ks)->parm->workload)
+               send_sig(SIGINT, G(ks)->trace_task, 0);
+
+       while (!ks->stop) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               /* sleep for 100 msecs, and try again. */
+               schedule_timeout(HZ / 10);
+
+               if (signal_pending(current)) {
+                       flush_signals(current);
+
+                       /* newline for handle CTRL+C display as ^C */
+                       kp_puts(ks, "\n");
+                       break;
+               }
+
+               /* stop waiting if target pid is exited */
+               if (task && task->state == TASK_DEAD)
+                               break;
+       }
+
+}
+
+void kp_exit(ktap_state *ks)
+{
+       set_next_as_exit(ks);
+
+       G(ks)->mainthread->stop = 1;
+       G(ks)->exit = 1;
+}
+
+void kp_final_exit(ktap_state *ks)
+{
+       if (!list_empty(&G(ks)->probe_events_head) ||
+           !list_empty(&G(ks)->timers))
+               kp_wait(ks);
+
+       if (G(ks)->trace_task)
+               put_task_struct(G(ks)->trace_task);
+
+       kp_exit_timers(ks);
+       kp_probe_exit(ks);
+
+       /* free all resources got by ktap */
+       kp_tstring_freeall(ks);
+       kp_free_all_gcobject(ks);
+       cfunction_cache_exit(ks);
+
+       wait_user_completion(ks);
+
+       kp_transport_exit(ks);
+
+       kp_exitthread(ks);
+       kp_free(ks, ks->stack);
+       free_all_ci(ks);
+
+       free_kp_percpu_data();
+
+       free_cpumask_var(G(ks)->cpumask);
+       kp_free(ks, ks);
+}
+
+/* ktap mainthread initization, main entry for ktap */
+ktap_state *kp_newstate(ktap_parm *parm, struct dentry *dir)
+{
+       ktap_state *ks;
+       pid_t pid;
+       int cpu;
+
+       ks = kzalloc(sizeof(ktap_state) + sizeof(ktap_global_state),
+                    GFP_KERNEL);
+       if (!ks)
+               return NULL;
+
+       ks->stack = kp_malloc(ks, KTAP_STACK_SIZE);
+       G(ks) = (ktap_global_state *)(ks + 1);
+       G(ks)->mainthread = ks;
+       G(ks)->seed = 201236; /* todo: make more random in future */
+       G(ks)->task = current;
+       G(ks)->parm = parm;
+       INIT_LIST_HEAD(&(G(ks)->timers));
+       INIT_LIST_HEAD(&(G(ks)->probe_events_head));
+       G(ks)->exit = 0;
+
+       if (kp_transport_init(ks, dir))
+               goto out;
+
+       pid = (pid_t)parm->trace_pid;
+       if (pid != -1) {
+               struct task_struct *task;
+
+               rcu_read_lock();
+               task = pid_task(find_vpid(pid), PIDTYPE_PID);
+               if (!task) {
+                       kp_error(ks, "cannot find pid %d\n", pid);
+                       rcu_read_unlock();
+                       goto out;
+               }
+               G(ks)->trace_task = task;
+               get_task_struct(task);
+               rcu_read_unlock();
+       }
+
+       if( !alloc_cpumask_var(&G(ks)->cpumask, GFP_KERNEL))
+               goto out;
+
+       cpumask_copy(G(ks)->cpumask, cpu_online_mask);
+
+       cpu = parm->trace_cpu;
+       if (cpu != -1) {
+               if (!cpu_online(cpu)) {
+                       printk(KERN_INFO "ktap: cpu %d is not online\n", cpu);
+                       goto out;
+               }
+
+               cpumask_clear(G(ks)->cpumask);
+               cpumask_set_cpu(cpu, G(ks)->cpumask);
+       }
+
+       if (cfunction_cache_init(ks))
+               goto out;
+
+       kp_tstring_resize(ks, 512); /* set inital string hashtable size */
+
+       kp_init_state(ks);
+       kp_init_registry(ks);
+       kp_init_arguments(ks, parm->argc, parm->argv);
+
+       /* init library */
+       kp_init_baselib(ks);
+       kp_init_kdebuglib(ks);
+       kp_init_timerlib(ks);
+       kp_init_ansilib(ks);
+
+       if (alloc_kp_percpu_data())
+               goto out;
+
+       if (kp_probe_init(ks))
+               goto out;
+
+       return ks;
+
+ out:
+       G(ks)->exit = 1;
+       kp_final_exit(ks);
+       return NULL;
+}
+
diff --git a/drivers/staging/ktap/scripts/basic/backtrace.kp b/drivers/staging/ktap/scripts/basic/backtrace.kp
new file mode 100644 (file)
index 0000000..39b8c39
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/env ktap
+
+trace sched:sched_switch {
+       print_backtrace()
+}
+
diff --git a/drivers/staging/ktap/scripts/basic/event_trigger.kp b/drivers/staging/ktap/scripts/basic/event_trigger.kp
new file mode 100644 (file)
index 0000000..3cc8b04
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env ktap
+
+soft_disabled = 1
+this_cpu = 0
+
+trace syscalls:sys_enter_open {
+       print(argevent)
+       soft_disabled = 0
+       this_cpu = cpu()
+}
+
+trace *:* {
+       if (soft_disabled == 0 && cpu() == this_cpu) {
+               print(argevent)
+       }
+}
+
+trace syscalls:sys_exit_open {
+       print(argevent)
+       if (cpu() == this_cpu) {
+               exit()
+       }
+}
+
diff --git a/drivers/staging/ktap/scripts/basic/event_trigger_ftrace.kp b/drivers/staging/ktap/scripts/basic/event_trigger_ftrace.kp
new file mode 100644 (file)
index 0000000..7e0d7d3
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/env ktap
+
+
+#This ktap script will output all function calling between
+#sys_enter_open and sys_exit_open, in one cpu.
+
+soft_disabled = 1
+this_cpu = 0
+
+trace syscalls:sys_enter_open {
+       print(argevent)
+       soft_disabled = 0
+       this_cpu = cpu()
+}
+
+trace ftrace:function {
+       if (soft_disabled == 0 && cpu() == this_cpu) {
+               print(argevent)
+       }
+}
+
+trace syscalls:sys_exit_open {
+       print(argevent)
+       if (cpu() == this_cpu) {
+               exit()
+       }
+}
+
diff --git a/drivers/staging/ktap/scripts/basic/ftrace.kp b/drivers/staging/ktap/scripts/basic/ftrace.kp
new file mode 100644 (file)
index 0000000..9feca2b
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/env ktap
+
+trace ftrace:function /ip==mutex*/ {
+       print(cpu(), pid(), execname(), argevent)
+}
+
diff --git a/drivers/staging/ktap/scripts/basic/function_time.kp b/drivers/staging/ktap/scripts/basic/function_time.kp
new file mode 100644 (file)
index 0000000..e7859a3
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/env ktap
+
+#Demo for thread-local variable
+#
+#Note this kind of function time tracing already handled concurrent issue,
+#but not aware on the recursion problem, user need to aware this limitation,
+#so don't use this script to trace function which could be called recursive.
+
+self = {}
+count_max = 0
+count_min = 0
+count_num = 0
+total_time = 0
+
+printf("measure time(us) of function vfs_read\n");
+
+trace probe:vfs_read {
+       if (execname() == "ktap") {
+               return
+       }
+
+       self[tid()] = gettimeofday_us()
+}
+
+trace probe:vfs_read%return {
+       if (execname() == "ktap") {
+               return
+       }
+
+       if (self[tid()] == nil) {
+               return
+       }
+
+       local durtion = gettimeofday_us() - self[tid()]
+       if (durtion > count_max) {
+               count_max = durtion
+       }
+       local min = count_min
+       if (min == 0 || durtion < min) {
+               count_min = durtion
+       }
+
+       count_num = count_num + 1
+       total_time = total_time + durtion
+
+       self[tid()] = nil
+}
+
+trace_end {
+       printf("avg\tmax\tmin\n");
+       printf("-------------------\n")
+
+       printf("%d\t%d\t%d\n", total_time/count_num,
+               count_max, count_min)
+}
+
+
diff --git a/drivers/staging/ktap/scripts/basic/kretprobe.kp b/drivers/staging/ktap/scripts/basic/kretprobe.kp
new file mode 100644 (file)
index 0000000..82de3cf
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/env ktap
+
+trace probe:vfs_read%return fd=$retval {
+       print(execname(), argevent);
+}
+
diff --git a/drivers/staging/ktap/scripts/game/tetris.kp b/drivers/staging/ktap/scripts/game/tetris.kp
new file mode 100644 (file)
index 0000000..7125cd4
--- /dev/null
@@ -0,0 +1,328 @@
+#!/usr/bin/env ktap
+#
+# Tetris KTAP Script
+#
+# Copyright (C) 2013/OCT/05 Tadaki SAKAI
+#
+# based on stapgames (Systemtap Game Collection)
+#   https://github.com/mhiramat/stapgames/blob/master/games/tetris.stp
+#
+#   - Requirements
+#     Kernel Configuration: CONFIG_KPROBE_EVENT=y
+#                           CONFIG_EVENT_TRACING=y
+#                           CONFIG_PERF_EVENTS=y
+#                           CONFIG_DEBUG_FS=y
+#     CPU Architecture : x86_64
+#
+#   - Setup
+#     $ sudo mount -t debugfs none /sys/kernel/debug/
+#
+#     $ git clone https://github.com/ktap/ktap
+#     $ cd ktap
+#     $ make 2>&1 | tee ../make.log
+#     $ sudo make load
+#     $ sudo sh -c 'echo 50000 > /sys/module/ktapvm/parameters/max_exec_count'
+#
+#   - Run Tetris
+#     $ sudo ./ktap scripts/game/tetris.kp
+#
+#
+# utils
+#
+function rand(max) {
+       r = gettimeofday_us()
+       if (r < 0) {
+               r = r * -1
+       }
+       return r % max
+}
+color_table = {}
+color_table["Black"]   = 40
+color_table["Red"]     = 41
+color_table["Green"]   = 42
+color_table["Yellow"]  = 43
+color_table["Blue"]    = 44
+color_table["Purple"]  = 45
+color_table["Cyan"]    = 46
+color_table["White"]   = 47
+function get_color_number(txt) {
+       return color_table[txt]
+}
+color_table_text = {}
+color_table_text[40] = "Black"
+color_table_text[41] = "Red"
+color_table_text[42] = "Green"
+color_table_text[43] = "Yellow"
+color_table_text[44] = "Blue"
+color_table_text[45] = "Purple"
+color_table_text[46] = "Cyan"
+color_table_text[47] = "White"
+function get_color_text(num) {
+       return color_table_text[num]
+}
+
+function update_display() {
+       for (i = 0, 239, 1) {
+               if ((i % 12 - 11) != 0) {
+                       tmp = ""
+               } else {
+                       tmp = "\n"
+               }
+
+               if (display_buffer[240 + i] == back_text) {
+                       printf("%s%s", back_text, tmp)
+               } else {
+                       ctext = display_buffer[240 + i]
+                       ansi.set_color2(get_color_number(ctext), 
+                                       get_color_number(ctext))
+                       printf("  %s", tmp)
+                       ansi.reset_color()
+               }
+
+               # clear the display buffer
+               display_buffer[240 + i] = display_buffer[i]
+       }
+
+       printf("%d\n",point)
+}
+
+#
+# global value
+#
+key_code = 0
+point = 0
+block_number = 0
+height = 0
+height_update = 0
+destination_position = {}
+back_text = {}
+block_color = {}
+display_buffer = {}
+block_data0 = {}
+block_data1 = {}
+block_data2 = {}
+block_data3 = {}
+block_data4 = {}
+block_data5 = {}
+block_data6 = {}
+block_table = {}
+#
+# Initialize
+#
+# Create blocks
+# block is represented by the position from the center.
+# Every block has "L" part in the center except for a bar.
+block_data0[0] = -11 # non-"L" part for each block
+block_data1[0] = -24
+block_data2[0] = 2
+block_data3[0] = 13
+block_data4[0] = -13
+block_data5[0] = -1
+block_data6[0] = 2
+       
+block_table[0] = block_data0
+block_table[1] = block_data1
+block_table[2] = block_data2
+block_table[3] = block_data3
+block_table[4] = block_data4
+block_table[5] = block_data5
+block_table[6] = block_data6
+for (i = 0, len(block_table) - 1, 1) {
+       # common "L" part
+       block_table[i][1] = 0
+       block_table[i][2] = 1
+       block_table[i][3] = -12
+}
+block_table[6][3] = -1 # bar is not common
+# Position: 1 row has 12 columns, 
+# and (x, y) is represented by h = x + y * 12.p
+height = 17 # First block position (center)
+
+for (i = 0, 240, 1) {
+       # Wall and Floor (sentinel)
+       if (((i % 12) < 2) || (i > 228)) {
+               block_color = "White"
+               tmp = block_color
+       } else {
+               back_text = "  "
+               tmp = back_text
+       }
+       display_buffer[i - 1] = tmp
+       display_buffer[240 + i - 1] = tmp
+}
+
+block_number = rand(len(color_table) - 1)
+block_color = get_color_text(block_number + 40)
+
+ansi.clear_screen()
+#
+# Key Input
+#
+trace probe:kbd_event handle=%di event_type=%si event_code=%dx value=%cx {
+       # Only can run it in x86_64
+       #
+       # Register follow x86_64 call conversion:
+       #
+       # x86_64:
+       #       %rcx    4 argument
+       #       %rdx    3 argument
+       #       %rsi    2 argument
+       #       %rdi    1 argument
+       local event_code = arg4
+       local value = arg5
+       if (value != 0) {
+               if ((event_code - 4) != 0) {
+                       key_code = event_code
+               }
+       }
+}
+#
+# timer
+#
+tick-200ms {
+       ansi.clear_screen()
+       f = 0 # move/rotate flag
+       if (key_code != 0) { # if key is pressed
+               if(key_code != 103) { #move left or right
+                       # d: movement direction
+                       if ((key_code - 105) != 0) {
+                               if ((key_code - 106) != 0) {
+                                       d = 0
+                               } else {
+                                       d = 1
+                               }
+                       } else {
+                               d = -1
+                       }
+                       for (i = 0, 3, 1) { # check if the block can be moved
+                               # destination is free
+                               if (display_buffer[height +
+                                       block_table[block_number][i] + d] 
+                                   != back_text) {
+                                       f = 1
+                               }
+                       }
+                       # move if destinations of every block are free
+                       if (f == 0) {
+                               height = height + d
+                       } 
+               } else { # rotate
+                       for (i = 0, 3, 1) { # check if block can be rotated
+                               # each block position
+                               p = block_table[block_number][i]
+                               # destination x pos(p/12 rounded)
+                               v = (p * 2 + 252) / 24 - 10
+                               w = p - v * 12 # destination y pos
+                               # destination position
+                               destination_position[i] = w * 12 - v
+                               # check if desetination is free
+                               if (display_buffer[height +
+                                   destination_position[i]] != back_text) {
+                                       f = 1
+                               }
+                       }
+                       if (f == 0) {
+                               # rotate if destinations of every block
+                               # are free
+                               for (i = 0, 3, 1) {
+                                       block_table[block_number][i] = 
+                                               destination_position[i] 
+                               }
+                       }
+               }
+       }
+       key_code = 0 # clear the input key
+       f = 0
+       for (i = 0, 3, 1) { # drop 1 row
+               # check if destination is free
+               p = height + block_table[block_number][i]
+               if (display_buffer[12 + p] != back_text) {
+                       f = 1
+               }
+               # copy the moving block to display buffer
+               display_buffer[240 + p] = block_color
+       }
+
+       if ((f == 1) && (height == 17)) {
+               update_display()
+               exit() # exit if there are block at initial position
+       }
+       height_update = !height_update
+       if (height_update != 0) {
+               if(f != 0) { # the block can't drop anymore
+                       for (i = 0, 3, 1) {
+                               # fix the block
+                               display_buffer[height + 
+                                 block_table[block_number][i]] = block_color 
+                       }
+                       # determin the next block
+                       block_number = rand(len(color_table) - 1)
+                       block_color = get_color_text(block_number + 40)
+                       height = 17 # make the block to initial position
+               } else {
+                       height = height + 12 # drop the block 1 row
+               }
+       }
+       k = 1
+       for (i = 18, 0, -1) { #check if line is filled
+               # search for filled line
+               j = 10
+               while ((j > 0) && 
+                      (display_buffer[i * 12 + j] != back_text)) {
+                       j = j - 1
+               }
+               if (j == 0) { # filled!
+                       # add a point: 1 line - 1 point, ..., tetris - 10points
+                       point = point + k
+                       k = k + 1
+                       # drop every upper block
+                       j = (i + 1) * 12
+                       i = i + 1
+                       while (j > 2 * 12) {
+                               j = j - 1
+                               display_buffer[j] = display_buffer[j - 12] 
+                       }
+               }
+       }
+       update_display()
+}
diff --git a/drivers/staging/ktap/scripts/helloworld.kp b/drivers/staging/ktap/scripts/helloworld.kp
new file mode 100644 (file)
index 0000000..5673c15
--- /dev/null
@@ -0,0 +1,3 @@
+#!/usr/bin/env ktap
+
+print("Hello World! I am ktap")
diff --git a/drivers/staging/ktap/scripts/interrupt/hardirq_time.kp b/drivers/staging/ktap/scripts/interrupt/hardirq_time.kp
new file mode 100644 (file)
index 0000000..1d3c33e
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/env ktap
+
+#this script output each average consumimg time of each hardirq
+s = aggr_table()
+map = {}
+
+trace irq:irq_handler_entry {
+       map[cpu()] = gettimeofday_us()
+}
+
+trace irq:irq_handler_exit {
+       local entry_time = map[cpu()]
+       if (entry_time == nil) {
+               return;
+       }
+
+       s[arg1] = avg(gettimeofday_us() - entry_time)
+       map[cpu()] = nil
+}
+
+trace_end {
+       print("hardirq average executing time (us)")
+       histogram(s)
+}
+
diff --git a/drivers/staging/ktap/scripts/interrupt/softirq_time.kp b/drivers/staging/ktap/scripts/interrupt/softirq_time.kp
new file mode 100644 (file)
index 0000000..7e1a9d8
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/env ktap
+
+#this script output each average consumimg time of each softirq line
+s = aggr_table()
+map = {}
+
+trace irq:softirq_entry {
+       map[cpu()] = gettimeofday_us()
+}
+
+trace irq:softirq_exit {
+       local entry_time = map[cpu()]
+       if (entry_time == nil) {
+               return;
+       }
+
+       s[arg1] = avg(gettimeofday_us() - entry_time)
+       map[cpu()] = nil
+}
+
+trace_end {
+       print("softirq average executing time (us)")
+       histogram(s)
+}
+
diff --git a/drivers/staging/ktap/scripts/io/kprobes-do-sys-open.kp b/drivers/staging/ktap/scripts/io/kprobes-do-sys-open.kp
new file mode 100644 (file)
index 0000000..a15f911
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env ktap
+
+#Only can run it in x86_64
+#
+#Register follow x86_64 call conversion:
+#
+#x86_64:
+#      %rcx    4 argument
+#      %rdx    3 argument
+#      %rsi    2 argument
+#      %rdi    1 argument
+
+trace probe:do_sys_open dfd=%di filename=%si flags=%dx mode=%cx {
+       printf("[do_sys_open entry]: (%s) open file (%s)\n",
+               execname(),  user_string(arg3))
+}
+
+trace probe:do_sys_open%return fd=$retval {
+       printf("[do_sys_open exit]:  return fd (%d)\n", arg3)
+}
diff --git a/drivers/staging/ktap/scripts/io/traceio.kp b/drivers/staging/ktap/scripts/io/traceio.kp
new file mode 100644 (file)
index 0000000..8a95a25
--- /dev/null
@@ -0,0 +1,56 @@
+#! /usr/bin/env ktap
+
+# Based on systemtap traceio.stp
+
+#this script is broken, fix it soon.
+
+reads = aggr_table()
+writes = aggr_table()
+total_io = aggr_table()
+
+trace syscalls:sys_exit_read {
+       reads[execname()] = sum(arg2)
+       total_io[execname()] = sum(arg2)
+}
+
+trace syscalls:sys_exit_write {
+       writes[execname()] = sum(arg2)
+       total_io[execname()] = sum(arg2)
+}
+
+function humanread_digit(bytes) {
+       if (bytes > 1024*1024*1024) {
+               return bytes/1024/1024/1024
+       } elseif (bytes > 1024*1024) {
+               return bytes/1024/1024
+       } elseif (bytes > 1024) {
+               return bytes/1024
+       } else {
+               return bytes
+       }
+}
+
+function humanread_x(bytes) {
+       if (bytes > 1024*1024*1024) {
+               return " GiB"
+       } elseif (bytes > 1024*1024) {
+               return " MiB"
+       } elseif (bytes > 1024) {
+               return " KiB"
+       } else {
+               return "   B"
+       }
+}
+
+tick-1s {
+       ansi.clear_screen()
+       for (exec, count in pairs(total_io)) {
+               local readnum = reads[exec]
+               local writenum = writes[exec]
+               printf("%15s r: %12d%s w: %12d%s\n", exec,
+                       humanread_digit(readnum), humanread_x(readnum),
+                       humanread_digit(writenum), humanread_x(writenum))
+       }
+       printf("\n")
+}
+
diff --git a/drivers/staging/ktap/scripts/mem/kmalloc-top.kp b/drivers/staging/ktap/scripts/mem/kmalloc-top.kp
new file mode 100644 (file)
index 0000000..f18ed9f
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/env ktap
+
+kmalloc_stack = {}
+
+trace kmem:kmalloc {
+       kmalloc_stack[backtrace()] += 1
+}
+
+tick-60s {
+       for (k, v in pairs(kmalloc_stack)) {
+               print(k)
+               printf("%d\n\n", v)
+       }
+
+       exit()
+}
+
diff --git a/drivers/staging/ktap/scripts/mem/kmem.kp b/drivers/staging/ktap/scripts/mem/kmem.kp
new file mode 100644 (file)
index 0000000..c6f2c99
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/bin/env ktap
+
+count1 = 0
+trace kmem:kmalloc {
+       count1 = count1 + 1
+}
+
+count2 = 0
+trace kmem:kfree {
+       count2 = count2 + 1
+}
+
+count3 = 0
+trace kmem:mm_page_alloc {
+       count3 = count3 + 1
+}
+
+count4 = 0
+trace kmem:mm_page_free {
+       count4 = count4 + 1
+}
+
+trace_end {
+       print("\n")
+       print("kmem:kmalloc:\t", count1)
+       print("kmem:kfree:\t", count2)
+       print("kmem:mm_page_alloc:", count3)
+       print("kmem:mm_page_free:", count4)
+       print("trace ending\n")
+}
diff --git a/drivers/staging/ktap/scripts/profiling/function_profiler.kp b/drivers/staging/ktap/scripts/profiling/function_profiler.kp
new file mode 100644 (file)
index 0000000..589017f
--- /dev/null
@@ -0,0 +1,41 @@
+#!/usr/bin/env ktap
+
+#kernel function profile
+#You can use this script to know what function is called frequently,
+#without enable CONFIG_FUNCTION_PROFILER in kernel.
+
+s = aggr_table()
+
+trace ftrace:function {
+       s[arg1] = count()
+}
+
+trace_end {
+       histogram(s)
+}
+
+#sample output
+#^C
+#                          value ------------- Distribution ------------- count
+#               sub_preempt_count | @@@@@                                  34904
+#               add_preempt_count | @@@@@                                  33435
+#              nsecs_to_jiffies64 | @@@                                    19919
+# irqtime_account_process_tick... | @                                      9970
+#               account_idle_time | @                                      9880
+#                  _raw_spin_lock |                                        5100
+#                _raw_spin_unlock |                                        5021
+#     _raw_spin_unlock_irqrestore |                                        4235
+#          _raw_spin_lock_irqsave |                                        4232
+#                 __rcu_read_lock |                                        3373
+#               __rcu_read_unlock |                                        3373
+#                  lookup_address |                                        2392
+#             pfn_range_is_mapped |                                        2384
+#      update_cfs_rq_blocked_load |                                        1983
+#                        idle_cpu |                                        1808
+#                       ktime_get |                                        1394
+#            _raw_spin_unlock_irq |                                        1270
+#              _raw_spin_lock_irq |                                        1091
+#                     update_curr |                                        950
+#             irqtime_account_irq |                                        950
+#                             ... |
+#
diff --git a/drivers/staging/ktap/scripts/profiling/stack_profile.kp b/drivers/staging/ktap/scripts/profiling/stack_profile.kp
new file mode 100644 (file)
index 0000000..9794560
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/env ktap
+
+# This ktap script samples stacktrace of system per 10us,
+# you can use generated output to make a flame graph.
+#
+# Flame Graphs:
+# http://dtrace.org/blogs/brendan/2012/03/17/linux-kernel-performance-flame-graphs/
+
+s = aggr_table()
+
+profile-10us {
+       s[backtrace()] = count()
+}
+
+tick-60s {
+       exit()
+}
+
+trace_end {
+       for (k, v in pairs(s)) {
+               print(k)
+               print(v)
+               print()
+       }
+}
+
diff --git a/drivers/staging/ktap/scripts/schedule/sched_transition.kp b/drivers/staging/ktap/scripts/schedule/sched_transition.kp
new file mode 100644 (file)
index 0000000..eb54b09
--- /dev/null
@@ -0,0 +1,5 @@
+#!/usr/bin/env ktap
+
+trace sched:sched_switch {
+       printf("%s ... ", arg1)
+}
diff --git a/drivers/staging/ktap/scripts/schedule/schedtimes.kp b/drivers/staging/ktap/scripts/schedule/schedtimes.kp
new file mode 100644 (file)
index 0000000..acef904
--- /dev/null
@@ -0,0 +1,125 @@
+#!/usr/vin/env ktap
+
+#schedtimer.kp
+#Initially inspired by Systemtap schedtimes.stp
+#and more bugfree compare with Systemtap's version
+#
+#Note that the time value is associate with pid, not with execname strictly,
+#sometime you will found there have sleep time for command "ls", the reason
+#is that sleep time is belong to parent process bash, so clear on this.
+
+RUNNING = 0
+QUEUED = 1
+SLEEPING = 2
+DEAD = 64
+
+run_time = {}
+queued_time = {}
+sleep_time = {}
+io_wait_time = {}
+
+pid_state = {}
+pid_names = {}
+prev_timestamp = {}
+io_wait = {}
+
+trace sched:sched_switch {
+       local prev_comm = arg1
+       local prev_pid = arg2
+       local prev_state = arg4
+       local next_comm = arg5
+       local next_pid = arg6
+       local t = gettimeofday_us()
+
+       if (pid_state[prev_pid] == nil) {
+               #do nothing
+       } elseif (pid_state[prev_pid] == RUNNING) {
+               run_time[prev_pid] += t - prev_timestamp[prev_pid]
+       } elseif (pid_state[prev_pid] == QUEUED) {
+               #found this:
+               #sched_wakeup comm=foo
+               #sched_switch prev_comm=foo
+               run_time[prev_pid] += t - prev_timestamp[prev_pid]
+       }
+
+       pid_names[prev_pid] = prev_comm
+       prev_timestamp[prev_pid] = t
+
+       if (prev_state == DEAD) {
+               pid_state[prev_pid] = DEAD
+       } elseif (prev_state > 0) {
+               if (in_iowait() == 1) {
+                       io_wait[prev_pid] = 1
+               }
+               pid_state[prev_pid] = SLEEPING
+       } elseif (prev_state == 0) {
+               pid_state[prev_pid] = QUEUED
+       }
+
+       if (pid_state[next_pid] == nil) {
+               pid_state[next_pid] = RUNNING
+       } elseif (pid_state[next_pid] == QUEUED) {
+               queued_time[next_pid] += t - prev_timestamp[next_pid]
+               pid_state[next_pid] = RUNNING
+       }
+
+       pid_names[next_pid] = next_comm
+       prev_timestamp[next_pid] = t
+}
+
+trace sched:sched_wakeup, sched:sched_wakeup_new {
+       local comm = arg1
+       local wakeup_pid = arg2
+       local success = arg4
+       local t = gettimeofday_us()
+
+       if (pid_state[wakeup_pid] == nil) {
+               #do nothing
+       } elseif (pid_state[wakeup_pid] == SLEEPING) {
+               local durtion = t - prev_timestamp[wakeup_pid]
+
+               sleep_time[wakeup_pid] += durtion
+               if (io_wait[wakeup_pid] == 1) {
+                       io_wait_time[wakeup_pid] += durtion
+                       io_wait[wakeup_pid] = 0
+               }
+       } elseif (pid_state[wakeup_pid] == RUNNING) {
+               return
+       }
+
+       pid_names[wakeup_pid] = comm
+       prev_timestamp[wakeup_pid] = t
+       pid_state[wakeup_pid] = QUEUED
+}
+
+trace_end {
+       local t = gettimeofday_us()
+       
+       for (pid, state in pairs(pid_state)) {
+               local durtion = t - prev_timestamp[pid]
+               if (state == SLEEPING) {
+                       sleep_time[pid] += durtion
+               } elseif (state == QUEUED) {
+                       queued_time[pid] += durtion
+               } elseif (state == RUNNING) {
+                       run_time[pid] += durtion
+               }
+       }
+
+       printf ("%16s: %6s %10s %10s %10s %10s %10s\n\n",
+               "execname", "pid", "run(us)", "sleep(us)", "io_wait(us)",
+               "queued(us)", "total(us)")
+
+       for (pid, time in pairs(run_time)) {
+               if (sleep_time[pid] == nil) {
+                       sleep_time[pid] = 0
+               }
+               if (queued_time[pid] == nil) {
+                       queue_time[pid] = 0
+               }
+               printf("%16s: %6d %10d %10d %10d %10d %10d\n",
+                       pid_names[pid], pid, run_time[pid], sleep_time[pid],
+                       io_wait_time[pid], queued_time[pid],
+                       run_time[pid] + sleep_time[pid] + queued_time[pid]);
+       }
+}
diff --git a/drivers/staging/ktap/scripts/syscalls/errinfo.kp b/drivers/staging/ktap/scripts/syscalls/errinfo.kp
new file mode 100644 (file)
index 0000000..049031b
--- /dev/null
@@ -0,0 +1,145 @@
+#!/usr/bin/env ktap
+
+#errdesc get from include/uapi/asm-generic/errno*.h
+errdesc = {
+       [1] = "Operation not permitted",                #EPERM
+       [2] = "No such file or directory",              #ENOENT
+       [3] = "No such process",                        #ESRCH
+       [4] = "Interrupted system call",                #EINRT
+       [5] = "I/O error",                              #EIO
+       [6] = "No such device or address",              #ENXIO
+       [7] = "Argument list too long",                 #E2BIG
+       [8] = "Exec format error",                      #ENOEXEC
+       [9] = "Bad file number",                        #EBADF
+       [10] = "No child processes",                    #ECHILD
+       [11] = "Try again",                             #EAGAIN
+       [12] = "Out of memory",                         #ENOMEM
+       [13] = "Permission denied",                     #EACCES
+       [14] = "Bad address",                           #EFAULT
+       [15] = "Block device required",                 #ENOTBLK
+       [16] = "Device or resource busy",               #EBUSY
+       [17] = "File exists",                           #EEXIST
+       [18] = "Cross-device link",                     #EXDEV
+       [19] = "No such device",                        #ENODEV
+       [20] = "Not a directory",                       #ENOTDIR
+       [21] = "Is a directory",                        #EISDIR
+       [22] = "Invalid argument",                      #EINVAL
+       [23] = "File table overflow",                   #ENFILE
+       [24] = "Too many open files",                   #EMFILE
+       [25] = "Not a typewriter",                      #ENOTTY
+       [26] = "Text file busy",                        #ETXTBSY
+       [27] = "File too large",                        #EFBIG
+       [28] = "No space left on device",               #ENOSPC
+       [29] = "Illegal seek",                          #ESPIPE
+       [30] = "Read-only file system",                 #EROFS
+       [31] = "Too many links",                        #EMLINK
+       [32] = "Broken pipe",                           #EPIPE
+       [33] = "Math argument out of domain of func",   #EDOM
+       [34] = "Math result not representable",         #ERANGE
+
+       [35] = "Resource deadlock would occur",         #EDEADLK
+       [36] = "File name too long",                    #ENAMETOOLONG
+       [37] = "No record locks available",             #ENOLCK
+       [38] = "Function not implemented",              #ENOSYS
+       [39] = "Directory not empty",                   #ENOTEMPTY              
+       [40] = "Too many symbolic links encountered",   #ELOOP
+       [42] = "No message of desired type",            #ENOMSG
+       [43] = "Identifier removed",                    #EIDRM
+       [44] = "Channel number out of range",           #ECHRNG
+       [45] = "Level 2 not synchronized",              #EL2NSYNC
+       [46] = "Level 3 halted",                        #EL3HLT
+       [47] = "Level 3 reset",                         #EL3RST                 
+       [48] = "Link number out of range",              #ELNRNG
+       [49] = "Protocol driver not attached",          #EUNATCH
+       [50] = "No CSI structure available",            #ENOCSI
+       [51] = "Level 2 halted",                        #EL2HLT
+       [52] = "Invalid exchange",                      #EBADE
+       [53] = "Invalid request descriptor",            #EBADR
+       [54] = "Exchange full",                         #EXFULL
+       [55] = "No anode",                              #ENOANO
+       [56] = "Invalid request code",                  #EBADRQC
+       [57] = "Invalid slot",                          #EBADSLT
+
+       [59] = "Bad font file format",                  #EBFONT
+       [60] = "Device not a stream",                   #ENOSTR
+       [61] = "No data available",                     #ENODATA
+       [62] = "Timer expired",                         #ETIME
+       [63] = "Out of streams resources",              #ENOSR
+       [64] = "Machine is not on the network",         #ENONET
+       [65] = "Package not installed",                 #ENOPKG
+       [66] = "Object is remote",                      #EREMOTE
+       [67] = "Link has been severed",                 #ENOLINK
+       [68] = "Advertise error",                       #EADV
+       [69] = "Srmount error",                         #ESRMNT
+       [70] = "Communication error on send",           #ECOMM
+       [71] = "Protocol error",                        #EPROTO
+       [72] = "Multihop attempted",                    #EMULTIHOP
+       [73] = "RFS specific error",                    #EDOTDOT
+       [74] = "Not a data message",                    #EBADMSG
+       [75] = "Value too large for defined data type", #EOVERFLOW
+       [76] = "Name not unique on network",            #ENOTUNIQ
+       [77] = "File descriptor in bad state",          #EBADFD
+       [78] = "Remote address changed",                #EREMCHG
+       [79] = "Can not access a needed shared library", #ELIBACC
+       [80] = "Accessing a corrupted shared library",  #ELIBBAD
+       [81] = ".lib section in a.out corrupted",       #ELIBSCN
+       [82] = "Attempting to link in too many shared libraries", #ELIBMAX
+       [83] = "Cannot exec a shared library directly", #ELIBEXEC
+       [84] = "Illegal byte sequence",                 #EILSEQ
+       [85] = "Interrupted system call should be restarted", #ERESTART
+       [86] = "Streams pipe error",                    #ESTRPIPE
+       [87] = "Too many users",                        #EUSERS
+       [88] = "Socket operation on non-socket",        #ENOTSOCK
+       [89] = "Destination address required",          #EDESTADDRREQ
+       [90] = "Message too long",                      #EMSGSIZE
+       [91] = "Protocol wrong type for socket",        #EPROTOTYPE
+       [92] = "Protocol not available",                #ENOPROTOOPT
+       [93] = "Protocol not supported",                #EPROTONOSUPPORT
+       [94] = "Socket type not supported",             #ESOCKTNOSUPPORT
+       [95] = "Operation not supported on transport endpoint", #EOPNOTSUPP
+       [96] = "Protocol family not supported",         #EPFNOSUPPORT
+       [97] = "Address family not supported by protocol", #EAFNOSUPPORT
+       [98] = "Address already in use",                #EADDRINUSE
+       [99] = "Cannot assign requested address",       #EADDRNOTAVAIL
+       [100] = "Network is down",                      #ENETDOWN
+       [101] = "Network is unreachable",               #ENETUNREACH
+       [102] = "Network dropped connection because of reset",  #ENETRESET
+       [103] = "Software caused connection abort",     #ECONNABORTED
+       [104] = "Connection reset by peer",             #ECONNRESET
+       [105] = "No buffer space available",            #ENOBUFS
+       [106] = "Transport endpoint is already connected", #EISCONN
+       [107] = "Transport endpoint is not connected",  #ENOTCONN
+       [108] = " Cannot send after transport endpoint shutdown", #ESHUTDOWN
+       [109] = "Too many references: cannot splice",   #ETOOMANYREFS
+       [110] = "Connection timed out",                 #ETIMEDOUT
+       [111] = "Connection refused",                   #ECONNREFUSED
+       [112] = "Host is down",                         #EHOSTDOWN
+       [113] = "No route to host",                     #EHOSTUNREACH
+       [114] = "Operation already in progress",        #EALREADY
+       [115] = "Operation now in progress",            #EINPROGRESS
+       [116] = "Stale NFS file handle",                #ESTALE
+       [117] = "Structure needs cleaning",             #EUCLEAN
+       [118] = "Not a XENIX named type file",          #ENOTNAM
+       [119] = "No XENIX semaphores available",        #ENAVAIL
+       [120] = "Is a named type file",                 #EISNAM
+       [121] = "Remote I/O error",                     #EREMOTEIO
+       [122] = "Quota exceeded",                       #EDQUOT
+       [123] = "No medium found",                      #ENOMEDIUM
+       [124] = "Wrong medium type",                    #EMEDIUMTYPE
+       [125] = "Operation Canceled",                   #ECANCELED
+       [126] = "Required key not available",           #ENOKEY
+       [127] = "Key has expired",                      #EKEYEXPIRED
+       [128] = "Key has been revoked",                 #EKEYREVOKED
+       [129] = "Key was rejected by service",          #EKEYREJECTED
+       [130] = "Owner died",                           #EOWNERDEAD
+       [131] = "State not recoverable",                #ENOTRECOVERABLE
+
+}
+
+trace syscalls:sys_exit_* {
+       if (arg2 < 0) {
+               local errno = -arg2
+               printf("%-15s%-20s\t%d\t%-30s\n",
+                       execname(), argname, errno, errdesc[errno])
+       }
+}
diff --git a/drivers/staging/ktap/scripts/syscalls/sctop.kp b/drivers/staging/ktap/scripts/syscalls/sctop.kp
new file mode 100644 (file)
index 0000000..6df45cb
--- /dev/null
@@ -0,0 +1,14 @@
+#! /usr/bin/env ktap
+
+#this script is broken, fix it soon.
+s = {}
+
+trace syscalls:sys_enter_* {
+       s[argname] += 1
+}
+
+tick-5s {
+       ansi.clear_screen()
+       histogram(s)
+       delete(s)
+}
diff --git a/drivers/staging/ktap/scripts/syscalls/syscalls.kp b/drivers/staging/ktap/scripts/syscalls/syscalls.kp
new file mode 100644 (file)
index 0000000..8bbaaca
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/env ktap
+
+trace syscalls:* {
+       print(cpu(), pid(), execname(), argevent)
+}
+
diff --git a/drivers/staging/ktap/scripts/syscalls/syscalls_count.kp b/drivers/staging/ktap/scripts/syscalls/syscalls_count.kp
new file mode 100644 (file)
index 0000000..363c622
--- /dev/null
@@ -0,0 +1,56 @@
+#!/usr/bin/env ktap
+
+s = aggr_table()
+
+trace syscalls:sys_enter_* {
+       s[argname] = count()
+}
+
+trace_end {
+       histogram(s)
+}
+
+print("Press Control-C to stop.")
+
+#Result:
+#
+#[root@jovi ktap]# ./ktap scripts/syscalls_histogram.kp
+#^C
+#                          value ------------- Distribution ------------- count
+#        sys_enter_rt_sigprocmask |@@@@@@                                 326
+#                  sys_enter_read |@@@@@                                  287
+#                 sys_enter_close |@@@@                                   236
+#                  sys_enter_open |@@@@                                   222
+#                sys_enter_stat64 |@@                                     132
+#                sys_enter_select |@@                                     123
+#          sys_enter_rt_sigaction |@@                                     107
+#                  sys_enter_poll |@                                      72
+#                 sys_enter_write |@                                      70
+#            sys_enter_mmap_pgoff |@                                      58
+#               sys_enter_fstat64 |                                       41
+#             sys_enter_nanosleep |                                       23
+#                sys_enter_access |                                       20
+#              sys_enter_mprotect |                                       18
+#               sys_enter_geteuid |                                       17
+#               sys_enter_getegid |                                       16
+#                sys_enter_getuid |                                       16
+#                sys_enter_getgid |                                       16
+#                   sys_enter_brk |                                       15
+#               sys_enter_waitpid |                                       11
+#                  sys_enter_time |                                       10
+#                 sys_enter_ioctl |                                       9
+#                sys_enter_munmap |                                       9
+#               sys_enter_fcntl64 |                                       7
+#                  sys_enter_dup2 |                                       7
+#                 sys_enter_clone |                                       6
+#            sys_enter_exit_group |                                       6
+#                sys_enter_execve |                                       4
+#                  sys_enter_pipe |                                       3
+#          sys_enter_gettimeofday |                                       3
+#              sys_enter_getdents |                                       2
+#             sys_enter_getgroups |                                       2
+#              sys_enter_statfs64 |                                       2
+#                 sys_enter_lseek |                                       2
+#                sys_enter_openat |                                       1
+#              sys_enter_newuname |                                       1
+
diff --git a/drivers/staging/ktap/scripts/syscalls/syscalls_count_by_proc.kp b/drivers/staging/ktap/scripts/syscalls/syscalls_count_by_proc.kp
new file mode 100644 (file)
index 0000000..7b7d722
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env ktap
+
+s = aggr_table()
+
+trace syscalls:sys_enter_* {
+       s[execname()] = count()
+}
+
+trace_end {
+       histogram(s)
+}
+
+print("Press Control-C to stop.")
+
+#Result:
+#
+#[root@jovi ktap]# ./ktap scripts/syscalls_histogram2.kp
+#^C
+#                          value ------------- Distribution ------------- count
+#                            sshd |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      196
+#                          iscsid |@@@@                                   24
+#                        sendmail |@                                      9
+
+
diff --git a/drivers/staging/ktap/scripts/tracepoints/eventcount.kp b/drivers/staging/ktap/scripts/tracepoints/eventcount.kp
new file mode 100644 (file)
index 0000000..9bc357f
--- /dev/null
@@ -0,0 +1,212 @@
+#!/usr/bin/env ktap
+
+# showing all tracepoints in histogram style
+
+s = {}
+
+trace *:* {
+       s[argname] += 1
+}
+
+trace_end {
+       histogram(s)
+}
+
+print("Press Control-C to stop.")
+
+#Results:
+#^C
+#
+#                          value ------------- Distribution ------------- count
+#                 rcu_utilization |@@@@@                                  225289
+#                        cpu_idle |@@@                                    120168
+#                    sched_wakeup |@@                                     91950
+#                    timer_cancel |@@                                     91232
+#                     timer_start |@@                                     91201
+#                sched_stat_sleep |@@                                     90981
+#               timer_expire_exit |@@                                     90634
+#              timer_expire_entry |@@                                     90625
+#                  hrtimer_cancel |@                                      75411
+#                   hrtimer_start |@                                      74946
+#                   softirq_raise |@                                      63117
+#                    softirq_exit |@                                      63109
+#                   softirq_entry |@                                      63094
+#                    sched_switch |@                                      62331
+#                 sched_stat_wait |@                                      60491
+#             hrtimer_expire_exit |@                                      47538
+#            hrtimer_expire_entry |@                                      47530
+#              sched_stat_runtime |                                       2780
+#                 kmem_cache_free |                                       2684
+#                kmem_cache_alloc |                                       2415
+#                           kfree |                                       2288
+#                        sys_exit |                                       2145
+#                       sys_enter |                                       2145
+#         sys_exit_rt_sigprocmask |                                       1000
+#        sys_enter_rt_sigprocmask |                                       1000
+#                      timer_init |                                       912
+#              sched_stat_blocked |                                       685
+#                         kmalloc |                                       667
+#           workqueue_execute_end |                                       621
+#         workqueue_execute_start |                                       621
+#                sys_enter_select |                                       566
+#                 sys_exit_select |                                       566
+#                  sys_enter_read |                                       526
+#                   sys_exit_read |                                       526
+#                    mm_page_free |                                       478
+#                   mm_page_alloc |                                       427
+#            mm_page_free_batched |                                       382
+#                   net_dev_queue |                                       296
+#                    net_dev_xmit |                                       296
+#                     consume_skb |                                       296
+#                  sys_exit_write |                                       290
+#                 sys_enter_write |                                       290
+#                       kfree_skb |                                       289
+#           kmem_cache_alloc_node |                                       269
+#                    kmalloc_node |                                       263
+#                 sys_enter_close |                                       249
+#                  sys_exit_close |                                       249
+#                    hrtimer_init |                                       248
+#               netif_receive_skb |                                       242
+#                  sys_enter_open |                                       237
+#                   sys_exit_open |                                       237
+#                       napi_poll |                                       226
+#              sched_migrate_task |                                       207
+#                   sys_exit_poll |                                       173
+#                  sys_enter_poll |                                       173
+#            workqueue_queue_work |                                       152
+#         workqueue_activate_work |                                       152
+#                sys_enter_stat64 |                                       133
+#                 sys_exit_stat64 |                                       133
+#           sys_exit_rt_sigaction |                                       133
+#          sys_enter_rt_sigaction |                                       133
+#               irq_handler_entry |                                       125
+#                irq_handler_exit |                                       125
+#       mm_page_alloc_zone_locked |                                       99
+#             sys_exit_mmap_pgoff |                                       66
+#            sys_enter_mmap_pgoff |                                       66
+#                sys_exit_fstat64 |                                       54
+#               sys_enter_fstat64 |                                       54
+#             sys_enter_nanosleep |                                       51
+#              sys_exit_nanosleep |                                       51
+#                 block_bio_queue |                                       46
+#                 block_bio_remap |                                       46
+#              block_bio_complete |                                       46
+#                  mix_pool_bytes |                                       44
+#              mm_page_pcpu_drain |                                       31
+#                   sys_exit_time |                                       23
+#                  sys_enter_time |                                       23
+#                 sys_exit_access |                                       20
+#                sys_enter_access |                                       20
+#           mix_pool_bytes_nolock |                                       18
+#              sys_enter_mprotect |                                       18
+#               sys_exit_mprotect |                                       18
+#               sys_enter_geteuid |                                       17
+#                sys_exit_geteuid |                                       17
+#                sys_enter_munmap |                                       17
+#                 sys_exit_munmap |                                       17
+#                     block_getrq |                                       16
+#                sys_enter_getuid |                                       16
+#                sys_enter_getgid |                                       16
+#                 sys_exit_getgid |                                       16
+#                 sys_exit_getuid |                                       16
+#                  block_rq_issue |                                       16
+#         scsi_dispatch_cmd_start |                                       16
+#               block_rq_complete |                                       16
+#          scsi_dispatch_cmd_done |                                       16
+#               sys_enter_getegid |                                       16
+#                sys_exit_getegid |                                       16
+#                 block_rq_insert |                                       16
+#         skb_copy_datagram_iovec |                                       15
+#                   sys_enter_brk |                                       15
+#                    sys_exit_brk |                                       15
+#             credit_entropy_bits |                                       14
+#                   wbc_writepage |                                       14
+#                  sys_exit_clone |                                       12
+#              block_touch_buffer |                                       12
+#              sched_process_wait |                                       11
+#               sys_enter_waitpid |                                       11
+#                sys_exit_waitpid |                                       11
+#               writeback_written |                                       10
+#                 writeback_start |                                       10
+#              writeback_queue_io |                                       10
+#     ext4_es_lookup_extent_enter |                                       9
+#                 sys_enter_ioctl |                                       9
+#                  sys_exit_ioctl |                                       9
+#       ext4_ext_map_blocks_enter |                                       9
+#        ext4_ext_map_blocks_exit |                                       9
+#      ext4_es_lookup_extent_exit |                                       9
+#           ext4_es_insert_extent |                                       9
+#            ext4_ext_show_extent |                                       8
+#                 extract_entropy |                                       8
+#ext4_es_find_delayed_extent_exit |                                       8
+# ext4_es_find_delayed_extent_... |                                       8
+#         writeback_pages_written |                                       7
+#                   sys_exit_dup2 |                                       7
+#                  sys_enter_dup2 |                                       7
+#                 signal_generate |                                       7
+#               sys_enter_fcntl64 |                                       7
+#                sys_exit_fcntl64 |                                       7
+#              global_dirty_state |                                       7
+#     writeback_dirty_inode_start |                                       7
+#             block_bio_backmerge |                                       7
+#           writeback_dirty_inode |                                       7
+#                sched_wakeup_new |                                       6
+#              sched_process_free |                                       6
+#            sys_enter_exit_group |                                       6
+#                    task_newtask |                                       6
+#                 sys_enter_clone |                                       6
+#              sched_process_fork |                                       6
+#              sched_process_exit |                                       6
+#           sys_exit_gettimeofday |                                       5
+#                  signal_deliver |                                       5
+#          sys_enter_gettimeofday |                                       5
+#          writeback_single_inode |                                       4
+#                sys_enter_execve |                                       4
+#                     task_rename |                                       4
+#              sched_process_exec |                                       4
+#              block_dirty_buffer |                                       4
+#                 sys_exit_execve |                                       4
+#                    block_unplug |                                       4
+#               sched_stat_iowait |                                       4
+#    writeback_single_inode_start |                                       4
+#                      block_plug |                                       4
+#           writeback_write_inode |                                       3
+#                  sys_enter_pipe |                                       3
+#            writeback_dirty_page |                                       3
+#     writeback_write_inode_start |                                       3
+#           ext4_mark_inode_dirty |                                       3
+#              ext4_journal_start |                                       3
+#                   sys_exit_pipe |                                       3
+#           jbd2_drop_transaction |                                       2
+#             jbd2_commit_locking |                                       2
+#            jbd2_commit_flushing |                                       2
+#               jbd2_handle_start |                                       2
+#                  jbd2_run_stats |                                       2
+#               sys_exit_getdents |                                       2
+#           jbd2_checkpoint_stats |                                       2
+#             sys_enter_getgroups |                                       2
+#               jbd2_start_commit |                                       2
+#                 jbd2_end_commit |                                       2
+#              ext4_da_writepages |                                       2
+#               jbd2_handle_stats |                                       2
+#              sys_enter_statfs64 |                                       2
+#               sys_exit_statfs64 |                                       2
+#              sys_exit_getgroups |                                       2
+#                  sys_exit_lseek |                                       2
+#                 sys_enter_lseek |                                       2
+#              sys_enter_getdents |                                       2
+#             ext4_da_write_pages |                                       2
+#             jbd2_commit_logging |                                       2
+#             ext4_request_blocks |                                       1
+#                 sys_exit_openat |                                       1
+#     ext4_discard_preallocations |                                       1
+#              ext4_mballoc_alloc |                                       1
+#                sys_enter_openat |                                       1
+#       ext4_da_writepages_result |                                       1
+#            ext4_allocate_blocks |                                       1
+#              sys_enter_newuname |                                       1
+#    ext4_da_update_reserve_space |                                       1
+# ext4_get_reserved_cluster_alloc |                                       1
+#               sys_exit_newuname |                                       1
+#           writeback_wake_thread |                                       1
+
diff --git a/drivers/staging/ktap/scripts/tracepoints/eventcount_by_proc.kp b/drivers/staging/ktap/scripts/tracepoints/eventcount_by_proc.kp
new file mode 100644 (file)
index 0000000..8706f73
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/env ktap
+
+# showing all tracepoints in histogram style
+
+s = aggr_table()
+
+trace *:* {
+       s[execname()] = count()
+}
+
+trace_end {
+       histogram(s)
+}
+
+print("Press Control-C to stop.")
+
+#Results:
+#^C
+#                          value ------------- Distribution ------------- count
+#                       swapper/0 |@@@@@@@@@@@@                           354378
+#                       swapper/1 |@@@@@@@@@@                             284984
+#                              ps |@@@@                                   115697
+#                        ksmtuned |@@@                                    95857
+#                          iscsid |@@                                     80008
+#                             awk |@                                      30354
+#                      irqbalance |                                       16530
+#                       rcu_sched |                                       15892
+#                        sendmail |                                       14463
+#                     kworker/0:1 |                                       10540
+#                    kworker/u4:2 |                                       9250
+#                     kworker/1:2 |                                       7943
+#                           sleep |                                       7555
+#                           crond |                                       3911
+#                     ksoftirqd/0 |                                       3817
+#                            sshd |                                       2849
+#                 systemd-journal |                                       2209
+#                     migration/1 |                                       1601
+#                     migration/0 |                                       1350
+#                        dhclient |                                       1343
+#                 nm-dhcp-client. |                                       1208
+#                     ksoftirqd/1 |                                       1064
+#                      watchdog/1 |                                       966
+#                      watchdog/0 |                                       964
+#                      khugepaged |                                       776
+#                     dbus-daemon |                                       611
+#                         rpcbind |                                       607
+#                           gdbus |                                       529
+#                  NetworkManager |                                       399
+#                     jbd2/dm-1-8 |                                       378
+#                   modem-manager |                                       184
+#                  abrt-watch-log |                                       157
+#                         polkitd |                                       156
+#                   rs:main Q:Reg |                                       153
+#                    avahi-daemon |                                       151
+#                        rsyslogd |                                       102
+#                         systemd |                                       96
+#                    kworker/0:1H |                                       45
+#                          smartd |                                       30
+
diff --git a/drivers/staging/ktap/scripts/tracepoints/tracepoints.kp b/drivers/staging/ktap/scripts/tracepoints/tracepoints.kp
new file mode 100644 (file)
index 0000000..5d08869
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/env ktap
+
+trace *:* {
+       print(cpu(), pid(), execname(), argevent)
+}
+
diff --git a/drivers/staging/ktap/scripts/userspace/uprobes-malloc.kp b/drivers/staging/ktap/scripts/userspace/uprobes-malloc.kp
new file mode 100644 (file)
index 0000000..14c172f
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/env ktap
+
+trace probe:/lib/libc.so.6:0x000773c0 {
+       print("entry:", execname(), argevent)
+}
+
+trace probe:/lib/libc.so.6:0x000773c0%return {
+       print("exit:", execname(), argevent)
+}
diff --git a/drivers/staging/ktap/test/aggr_table.kp b/drivers/staging/ktap/test/aggr_table.kp
new file mode 100644 (file)
index 0000000..985b634
--- /dev/null
@@ -0,0 +1,50 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#---------------------------------#
+
+s = aggr_table()
+
+s["count"] = count()
+s["count"] = count()
+s["count"] = count()
+
+s["max"] = max(1)
+s["max"] = max(0)
+s["max"] = max(100)
+
+s["min"] = min(50)
+s["min"] = min(2)
+s["min"] = min(100)
+
+s["sum"] = sum(10)
+s["sum"] = sum(20)
+s["sum"] = sum(30)
+
+s["avg"] = avg(10)
+s["avg"] = avg(20)
+s["avg"] = avg(30)
+
+if (s["count"] != 3) {
+       failed()
+}
+
+if (s["max"] != 100) {
+       failed()
+}
+
+if (s["min"] != 2) {
+       failed()
+}
+
+if (s["sum"] != 60) {
+       failed()
+}
+
+if (s["avg"] != 20) {
+       failed()
+}
diff --git a/drivers/staging/ktap/test/ansi.kp b/drivers/staging/ktap/test/ansi.kp
new file mode 100644 (file)
index 0000000..e8a2783
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env ktap
+
+ansi.clear_screen()
+
+ansi.set_color(32)
+printf("this line should be Green color\n")
+
+ansi.set_color(31)
+printf("this line should be Red color\n")
+
+ansi.set_color2(34, 43)
+printf("this line should be Blue color, with Yellow background\n")
+
+ansi.reset_color()
+ansi.set_color3(34, 46, 4)
+printf("this line should be Blue color, with Cyan background, underline single attribute\n")
+
+ansi.reset_color()
+ansi.new_line()
+
diff --git a/drivers/staging/ktap/test/arg.kp b/drivers/staging/ktap/test/arg.kp
new file mode 100644 (file)
index 0000000..0cf16eb
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#-----------------------------------------#
+
+if (!arg[0]) {
+       failed()
+}
+
+if (arg[1] != 1) {
+       failed()
+}
+
+if (arg[2] != "testing") {
+       failed()
+}
+
+if (arg[3] != "2 3 4") {
+       failed()
+}
diff --git a/drivers/staging/ktap/test/arith.kp b/drivers/staging/ktap/test/arith.kp
new file mode 100644 (file)
index 0000000..32880a1
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#-----------------------------------------#
+
+a = 4
+b = 5
+
+if ((a + b) != 9) {
+       failed()
+}
+
+if ((a - b) != -1) {
+       failed()
+}
+
+if ((a % b) != 4) {
+       failed()
+}
+
+if ((a / b) != 0) {
+       failed()
+}
diff --git a/drivers/staging/ktap/test/bench/sembench.c b/drivers/staging/ktap/test/bench/sembench.c
new file mode 100644 (file)
index 0000000..0811934
--- /dev/null
@@ -0,0 +1,556 @@
+/*
+ * copyright Oracle 2007.  Licensed under GPLv2
+ * To compile: gcc -Wall -o sembench sembench.c -lpthread
+ *
+ * usage: sembench -t thread count -w wakenum -r runtime -o op
+ * op can be: 0 (ipc sem) 1 (nanosleep) 2 (futexes)
+ *
+ * example:
+ *     sembench -t 1024 -w 512 -r 60 -o 2
+ * runs 1024 threads, waking up 512 at a time, running for 60 seconds using
+ * futex locking.
+ *
+ */
+#define  _GNU_SOURCE
+#define _POSIX_C_SOURCE 199309
+#include <fcntl.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/sem.h>
+#include <sys/ipc.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+#include <errno.h>
+
+#define VERSION "0.2"
+
+/* futexes have been around since 2.5.something, but it still seems I
+ * need to make my own syscall.  Sigh.
+ */
+#define FUTEX_WAIT              0
+#define FUTEX_WAKE              1
+#define FUTEX_FD                2
+#define FUTEX_REQUEUE           3
+#define FUTEX_CMP_REQUEUE       4
+#define FUTEX_WAKE_OP           5
+static inline int futex (int *uaddr, int op, int val,
+                        const struct timespec *timeout,
+                        int *uaddr2, int val3)
+{
+       return syscall(__NR_futex, uaddr, op, val, timeout, uaddr2, val3);
+}
+
+static void smp_mb(void)
+{
+       __sync_synchronize();
+}
+
+static int all_done = 0;
+static int timeout_test = 0;
+
+#define SEMS_PERID 250
+
+struct sem_operations;
+
+struct lockinfo {
+       unsigned long id;
+       unsigned long index;
+       int data;
+       pthread_t tid;
+       struct lockinfo *next;
+       struct sem_operations *ops;
+       unsigned long ready;
+};
+
+struct sem_wakeup_info {
+       int wakeup_count;
+       struct sembuf sb[SEMS_PERID];
+};
+
+struct sem_operations {
+       void (*wait)(struct lockinfo *l);
+       int (*wake)(struct sem_wakeup_info *wi, int num_semids, int num);
+       void (*setup)(struct sem_wakeup_info **wi, int num_semids);
+       void (*cleanup)(int num_semids);
+       char *name;
+};
+
+int *semid_lookup = NULL;
+
+pthread_mutex_t worklist_mutex = PTHREAD_MUTEX_INITIALIZER;
+static unsigned long total_burns = 0;
+static unsigned long min_burns = ~0UL;
+static unsigned long max_burns = 0;
+
+/* currently running threads */
+static int thread_count = 0;
+
+struct lockinfo *worklist = NULL;
+static int workers_started = 0;
+
+/* total threads started */
+static int num_threads = 2048;
+
+static void worklist_add(struct lockinfo *l)
+{
+       smp_mb();
+       l->ready = 1;
+}
+
+static struct lockinfo *worklist_rm(void)
+{
+       static int last_index = 0;
+       int i;
+       struct lockinfo *l;
+
+       for (i = 0; i < num_threads; i++) {
+               int test = (last_index + i) % num_threads;
+
+               l = worklist + test;
+               smp_mb();
+               if (l->ready) {
+                       l->ready = 0;
+                       last_index = test;
+                       return l;
+               }
+       }
+       return NULL;
+}
+
+/* ipc semaphore post& wait */
+void wait_ipc_sem(struct lockinfo *l)
+{
+       struct sembuf sb;
+       int ret;
+       struct timespec *tvp = NULL;
+       struct timespec tv = { 0, 1 };
+
+       sb.sem_num = l->index;
+       sb.sem_flg = 0;
+
+       sb.sem_op = -1;
+       l->data = 1;
+
+       if (timeout_test && (l->id % 5) == 0)
+               tvp = &tv;
+
+       worklist_add(l);
+       ret = semtimedop(semid_lookup[l->id], &sb, 1, tvp);
+
+       while(l->data != 0 && tvp) {
+               struct timespec tv2 = { 0, 500 };
+               nanosleep(&tv2, NULL);
+       }
+
+       if (l->data != 0) {
+               if (tvp)
+                       return;
+               fprintf(stderr, "wakeup without data update\n");
+               exit(1);
+       }
+       if (ret) {
+               if (errno == EAGAIN && tvp)
+                       return;
+               perror("semtimed op");
+               exit(1);
+       }
+}
+
+int ipc_wake_some(struct sem_wakeup_info *wi, int num_semids, int num)
+{
+       int i;
+       int ret;
+       struct lockinfo *l;
+       int found = 0;
+
+       for (i = 0; i < num_semids; i++) {
+               wi[i].wakeup_count = 0;
+       }
+       while(num > 0) {
+               struct sembuf *sb;
+               l = worklist_rm();
+               if (!l)
+                       break;
+               if (l->data != 1)
+                       fprintf(stderr, "warning, lockinfo data was %d\n",
+                               l->data);
+               l->data = 0;
+               sb = wi[l->id].sb + wi[l->id].wakeup_count;
+               sb->sem_num = l->index;
+               sb->sem_op = 1;
+               sb->sem_flg = IPC_NOWAIT;
+               wi[l->id].wakeup_count++;
+               found++;
+               num--;
+       }
+       if (!found)
+               return 0;
+       for (i = 0; i < num_semids; i++) {
+               int wakeup_total;
+               int cur;
+               int offset = 0;
+               if (!wi[i].wakeup_count)
+                       continue;
+               wakeup_total = wi[i].wakeup_count;
+               while(wakeup_total > 0) {
+                       cur = wakeup_total > 64 ? 64 : wakeup_total;
+                       ret = semtimedop(semid_lookup[i], wi[i].sb + offset,
+                                        cur, NULL);
+                       if (ret) {
+                               perror("semtimedop");
+                               exit(1);
+                       }
+                       offset += cur;
+                       wakeup_total -= cur;
+               }
+       }
+       return found;
+}
+
+void setup_ipc_sems(struct sem_wakeup_info **wi, int num_semids)
+{
+       int i;
+       *wi = malloc(sizeof(**wi) * num_semids);
+       semid_lookup = malloc(num_semids * sizeof(int));
+       for(i = 0; i < num_semids; i++) {
+               semid_lookup[i] = semget(IPC_PRIVATE, SEMS_PERID,
+                                        IPC_CREAT | 0777);
+               if (semid_lookup[i] < 0) {
+                       perror("semget");
+                       exit(1);
+               }
+       }
+       sleep(10);
+}
+
+void cleanup_ipc_sems(int num)
+{
+       int i;
+       for (i = 0; i < num; i++) {
+               semctl(semid_lookup[i], 0, IPC_RMID);
+       }
+}
+
+struct sem_operations ipc_sem_ops = {
+       .wait = wait_ipc_sem,
+       .wake = ipc_wake_some,
+       .setup = setup_ipc_sems,
+       .cleanup = cleanup_ipc_sems,
+       .name = "ipc sem operations",
+};
+
+/* futex post & wait */
+void wait_futex_sem(struct lockinfo *l)
+{
+       int ret;
+       l->data = 1;
+       worklist_add(l);
+       while(l->data == 1) {
+               ret = futex(&l->data, FUTEX_WAIT, 1, NULL, NULL, 0);
+               /*
+               if (ret && ret != EWOULDBLOCK) {
+                       perror("futex wait");
+                       exit(1);
+               }*/
+       }
+}
+
+int futex_wake_some(struct sem_wakeup_info *wi, int num_semids, int num)
+{
+       int i;
+       int ret;
+       struct lockinfo *l;
+       int found = 0;
+
+       for (i = 0; i < num; i++) {
+               l = worklist_rm();
+               if (!l)
+                       break;
+               if (l->data != 1)
+                       fprintf(stderr, "warning, lockinfo data was %d\n",
+                               l->data);
+               l->data = 0;
+               ret = futex(&l->data, FUTEX_WAKE, 1, NULL, NULL, 0);
+               if (ret < 0) {
+                       perror("futex wake");
+                       exit(1);
+               }
+               found++;
+       }
+       return found;
+}
+
+void setup_futex_sems(struct sem_wakeup_info **wi, int num_semids)
+{
+       return;
+}
+
+void cleanup_futex_sems(int num)
+{
+       return;
+}
+
+struct sem_operations futex_sem_ops = {
+       .wait = wait_futex_sem,
+       .wake = futex_wake_some,
+       .setup = setup_futex_sems,
+       .cleanup = cleanup_futex_sems,
+       .name = "futex sem operations",
+};
+
+/* nanosleep sems here */
+void wait_nanosleep_sem(struct lockinfo *l)
+{
+       int ret;
+       struct timespec tv = { 0, 1000000 };
+       int count = 0;
+
+       l->data = 1;
+       worklist_add(l);
+       while(l->data) {
+               ret = nanosleep(&tv, NULL);
+               if (ret) {
+                       perror("nanosleep");
+                       exit(1);
+               }
+               count++;
+       }
+}
+
+int nanosleep_wake_some(struct sem_wakeup_info *wi, int num_semids, int num)
+{
+       int i;
+       struct lockinfo *l;
+
+       for (i = 0; i < num; i++) {
+               l = worklist_rm();
+               if (!l)
+                       break;
+               if (l->data != 1)
+                       fprintf(stderr, "warning, lockinfo data was %d\n",
+                               l->data);
+               l->data = 0;
+       }
+       return i;
+}
+
+void setup_nanosleep_sems(struct sem_wakeup_info **wi, int num_semids)
+{
+       return;
+}
+
+void cleanup_nanosleep_sems(int num)
+{
+       return;
+}
+
+struct sem_operations nanosleep_sem_ops = {
+       .wait = wait_nanosleep_sem,
+       .wake = nanosleep_wake_some,
+       .setup = setup_nanosleep_sems,
+       .cleanup = cleanup_nanosleep_sems,
+       .name = "nano sleep sem operations",
+};
+
+void *worker(void *arg)
+{
+       struct lockinfo *l = (struct lockinfo *)arg;
+       int burn_count = 0;
+       pthread_t tid = pthread_self();
+       size_t pagesize = getpagesize();
+       char *buf = malloc(pagesize);
+
+       if (!buf) {
+               perror("malloc");
+               exit(1);
+       }
+
+       l->tid = tid;
+       workers_started = 1;
+       smp_mb();
+
+       while(!all_done) {
+               l->ops->wait(l);
+               if (all_done)
+                       break;
+               burn_count++;
+       }
+       pthread_mutex_lock(&worklist_mutex);
+       total_burns += burn_count;
+       if (burn_count < min_burns)
+               min_burns = burn_count;
+       if (burn_count > max_burns)
+               max_burns = burn_count;
+       thread_count--;
+       pthread_mutex_unlock(&worklist_mutex);
+       return (void *)0;
+}
+
+void print_usage(void)
+{
+       printf("usage: sembench [-t threads] [-w wake incr] [-r runtime]");
+       printf("                [-o num] (0=ipc, 1=nanosleep, 2=futex)\n");
+       exit(1);
+}
+
+#define NUM_OPERATIONS 3
+struct sem_operations *allops[NUM_OPERATIONS] = { &ipc_sem_ops,
+                                               &nanosleep_sem_ops,
+                                               &futex_sem_ops};
+
+int main(int ac, char **av) {
+       int ret;
+       int i;
+       int semid = 0;
+       int sem_num = 0;
+       int burn_count = 0;
+       struct sem_wakeup_info *wi = NULL;
+       struct timeval start;
+       struct timeval now;
+       int num_semids = 0;
+       int wake_num = 256;
+       int run_secs = 30;
+       int pagesize = getpagesize();
+       char *buf = malloc(pagesize);
+       struct sem_operations *ops = allops[0];
+       cpu_set_t cpu_mask;
+       cpu_set_t target_mask;
+       int target_cpu = 0;
+       int max_cpu = -1;
+
+       if (!buf) {
+               perror("malloc");
+               exit(1);
+       }
+       for (i = 1; i < ac; i++) {
+               if (strcmp(av[i], "-t") == 0) {
+                       if (i == ac -1)
+                               print_usage();
+                       num_threads = atoi(av[i+1]);
+                       i++;
+               } else if (strcmp(av[i], "-w") == 0) {
+                       if (i == ac -1)
+                               print_usage();
+                       wake_num = atoi(av[i+1]);
+                       i++;
+               } else if (strcmp(av[i], "-r") == 0) {
+                       if (i == ac -1)
+                               print_usage();
+                       run_secs = atoi(av[i+1]);
+                       i++;
+               } else if (strcmp(av[i], "-o") == 0) {
+                       int index;
+                       if (i == ac -1)
+                               print_usage();
+                       index = atoi(av[i+1]);
+                       if (index >= NUM_OPERATIONS) {
+                               fprintf(stderr, "invalid operations %d\n",
+                                       index);
+                               exit(1);
+                       }
+                       ops = allops[index];
+                       i++;
+               } else if (strcmp(av[i], "-T") == 0) {
+                       timeout_test = 1;
+               } else if (strcmp(av[i], "-h") == 0) {
+                       print_usage();
+               }
+       }
+       num_semids = (num_threads + SEMS_PERID - 1) / SEMS_PERID;
+       ops->setup(&wi, num_semids);
+
+       ret = sched_getaffinity(0, sizeof(cpu_set_t), &cpu_mask);
+       if (ret) {
+               perror("sched_getaffinity");
+               exit(1);
+       }
+       for (i = 0; i < CPU_SETSIZE; i++)
+               if (CPU_ISSET(i, &cpu_mask))
+                       max_cpu = i;
+       if (max_cpu == -1) {
+               fprintf(stderr, "sched_getaffinity returned empty mask\n");
+               exit(1);
+       }
+
+       CPU_ZERO(&target_mask);
+
+       worklist = malloc(sizeof(*worklist) * num_threads);
+       memset(worklist, 0, sizeof(*worklist) * num_threads);
+
+       for (i = 0; i < num_threads; i++) {
+               struct lockinfo *l;
+               pthread_t tid;
+               thread_count++;
+               l = worklist + i;
+               if (!l) {
+                       perror("malloc");
+                       exit(1);
+               }
+               l->id = semid;
+               l->index = sem_num++;
+               l->ops = ops;
+               if (sem_num >= SEMS_PERID) {
+                       semid++;
+                       sem_num = 0;
+               }
+               ret = pthread_create(&tid, NULL, worker, (void *)l);
+               if (ret) {
+                       perror("pthread_create");
+                       exit(1);
+               }
+
+               while (!CPU_ISSET(target_cpu, &cpu_mask)) {
+                       target_cpu++;
+                       if (target_cpu > max_cpu)
+                               target_cpu = 0;
+               }
+               CPU_SET(target_cpu, &target_mask);
+               ret = pthread_setaffinity_np(tid, sizeof(cpu_set_t),
+                                            &target_mask);
+               CPU_CLR(target_cpu, &target_mask);
+               target_cpu++;
+
+               ret = pthread_detach(tid);
+               if (ret) {
+                       perror("pthread_detach");
+                       exit(1);
+               }
+       }
+       while(!workers_started) {
+               smp_mb();
+               usleep(200);
+       }
+       gettimeofday(&start, NULL);
+       fprintf(stderr, "main loop going\n");
+       while(1) {
+               ops->wake(wi, num_semids, wake_num);
+               burn_count++;
+               gettimeofday(&now, NULL);
+               if (now.tv_sec - start.tv_sec >= run_secs)
+                       break;
+       }
+       fprintf(stderr, "all done\n");
+       all_done = 1;
+       while(thread_count > 0) {
+               ops->wake(wi, num_semids, wake_num);
+               usleep(200);
+       }
+       printf("%d threads, waking %d at a time\n", num_threads, wake_num);
+       printf("using %s\n", ops->name);
+       printf("main thread burns: %d\n", burn_count);
+       printf("worker burn count total %lu min %lu max %lu avg %lu\n",
+              total_burns, min_burns, max_burns, total_burns / num_threads);
+       printf("run time %d seconds %lu worker burns per second\n",
+               (int)(now.tv_sec - start.tv_sec),
+               total_burns / (now.tv_sec - start.tv_sec));
+       ops->cleanup(num_semids);
+       return 0;
+}
+
diff --git a/drivers/staging/ktap/test/bench/test.sh b/drivers/staging/ktap/test/bench/test.sh
new file mode 100644 (file)
index 0000000..9f77969
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+gcc -o sembench sembench.c -O2 -lpthread
+
+COMMAND="./sembench -t 200 -w 20 -r 30 -o 2"
+
+echo -e "\n\t\tPass 1 without tracing"
+$COMMAND
+echo -e "\n\t\tPass 2 without tracing"
+$COMMAND
+echo -e "\n\t\tPass 3 without tracing"
+$COMMAND
+
+echo ""
+
+KTAP_ONE_LINER="trace syscalls:sys_*_futex {}"
+
+echo -e "\n\t\tPass 1 with tracing"
+../../ktap -e "$KTAP_ONE_LINER" -- $COMMAND
+echo -e "\n\t\tPass 2 with tracing"
+../../ktap -e "$KTAP_ONE_LINER" -- $COMMAND
+echo -e "\n\t\tPass 3 with tracing"
+../../ktap -e "$KTAP_ONE_LINER" -- $COMMAND
+
+rm -rf ./sembench
diff --git a/drivers/staging/ktap/test/concat.kp b/drivers/staging/ktap/test/concat.kp
new file mode 100644 (file)
index 0000000..be77bb7
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#----------------------------------------#
+
+a = "123"
+b = "456"
+
+if (a..b != "123456") {
+       failed()
+}
diff --git a/drivers/staging/ktap/test/count.kp b/drivers/staging/ktap/test/count.kp
new file mode 100644 (file)
index 0000000..26f962c
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#---------------------------------------#
+
+t = {}
+
+t["key"] += 1
+if (t["key"] != 1) {
+       failed()
+}
+
+t["key"] += 1
+if (t["key"] != 2) {
+       failed()
+}
diff --git a/drivers/staging/ktap/test/fibonacci.kp b/drivers/staging/ktap/test/fibonacci.kp
new file mode 100644 (file)
index 0000000..7e141da
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#---------------fibonacci----------------
+
+
+#regular recursive fibonacci
+function fib(n) {
+       if (n < 2) {
+               return n
+       }
+       return fib(n-1) + fib(n-2)
+}
+
+if (fib(20) != 6765) {
+       failed()
+}
+
+#tail recursive fibonacci
+function fib(n) {
+       f = function (iter, res, next) {
+               if (iter == 0) {
+                       return res;
+               }
+               return f(iter-1, next, res+next)
+       }
+       return f(n, 0, 1)
+}
+
+if (fib(20) != 6765) {
+       failed()
+}
diff --git a/drivers/staging/ktap/test/function.kp b/drivers/staging/ktap/test/function.kp
new file mode 100644 (file)
index 0000000..bfbff26
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+### basic function call ###
+function f1(a, b) {
+       return a + b
+}
+
+if (f1(2, 3) != 5) {
+       failed();
+}
+
+### return string ###
+function f2() {
+       return "function return"
+}
+
+if (f2() != "function return") {
+       failed();
+}
+
+### mutli-value return ###
+function f3(a, b) {
+       return a+b, a-b;
+}
+
+c, d = f3(2, 3);
+if(c != 5 || d != -1) {
+       failed();
+}
+
+
+### closure testing ### 
+function f4() {
+       f5 = function(a, b) {
+               return a * b
+       }
+       return f5
+}
+
+local f = f4()
+if (f(9, 9) != 81) {
+       failed();
+}
+
+### closure with lexcial variable ### 
+# issue: variable cannot be local
+i = 1
+function f6() {
+       i = 5
+       f7 = function(a, b) {
+               return a * b + i
+       }
+       return f7
+}
+
+f = f6()
+if (f(9, 9) != 81 + i) {
+       failed();
+}
+
+i = 6
+if (f(9, 9) != 81 + i) {
+       failed();
+}
+
+### tail call
+### stack should not overflow in tail call mechanism
+a = 0
+function f8(i) {
+       if (i == 1000000) {
+               a = 1000000
+               return
+       }
+       # must add return here, otherwise stack overflow
+       return f8(i+1)
+}
+
+f8(0)
+if (a != 1000000) {
+       failed();
+}
+
+
diff --git a/drivers/staging/ktap/test/if.kp b/drivers/staging/ktap/test/if.kp
new file mode 100644 (file)
index 0000000..3122084
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#-----------------------------------------#
+
+if (false) {
+       failed()
+}
+
+if (nil) {
+       failed()
+}
+
+# ktap only think false and nil is "real false", number 0 is true
+# it's same as lua
+# Might change it in future, to make similar with C
+if (0) {
+       #failed()
+}
+
diff --git a/drivers/staging/ktap/test/kprobe.kp b/drivers/staging/ktap/test/kprobe.kp
new file mode 100644 (file)
index 0000000..022d4a7
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/env ktap
+
+n = 0
+trace probe:schedule {
+       n = n + 1
+}
+
+tick-1s {
+       if (n == 0) {
+               printf("failed\n");
+       }
+       exit()
+}
+
diff --git a/drivers/staging/ktap/test/kretprobe.kp b/drivers/staging/ktap/test/kretprobe.kp
new file mode 100644 (file)
index 0000000..e311e84
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/env ktap
+
+n = 0
+trace probe:__schedule%return {
+       n = n + 1
+}
+
+tick-1s {
+       if (n == 0) {
+               printf("failed\n");
+       }
+       exit()
+}
+
diff --git a/drivers/staging/ktap/test/len.kp b/drivers/staging/ktap/test/len.kp
new file mode 100644 (file)
index 0000000..697d915
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#-----------------------------------------#
+
+a = "123456789"
+
+if (len(a) != 9) {
+       failed()
+}
+
+b = {}
+b[0] = 0
+b[1] = 1
+b["keys"] = "values"
+
+if (len(b) != 3) {
+       failed()
+}
+
+
diff --git a/drivers/staging/ktap/test/looping.kp b/drivers/staging/ktap/test/looping.kp
new file mode 100644 (file)
index 0000000..fe48051
--- /dev/null
@@ -0,0 +1,40 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+### basic while-loop testing
+a = 1
+while (a < 1000) {
+       a = a + 1
+}
+
+if (a != 1000) {
+       failed()
+}
+
+### break testing
+### Note that ktap don't have continue keyword
+a = 1
+while (a < 1000) {
+       if (a == 10) {
+               break
+       }
+       a = a + 1
+}
+
+if (a != 10) {
+       failed()
+}
+
+### for-loop testing
+b=0
+for (c = 0, 1000, 1) {
+       b = b + 1
+}
+
+if (b != 1001) {
+       failed()
+}
diff --git a/drivers/staging/ktap/test/pairs.kp b/drivers/staging/ktap/test/pairs.kp
new file mode 100644 (file)
index 0000000..cdf3825
--- /dev/null
@@ -0,0 +1,45 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#-----------------------------------------#
+
+t = {}
+t[1] = 101
+t[2] = 102
+t[3] = 103
+t["key_1"] = "value_1"
+t["key_2"] = "value_2"
+t["key_3"] = "value_3"
+
+local n = 0
+
+for (k, v in pairs(t)) {
+       n = n + 1
+
+       if (k == 1 && v != 101) {
+               failed()
+       }
+       if (k == 2 && v != 102) {
+               failed()
+       }
+       if (k == 3 && v != 103) {
+               failed()
+       }
+       if (k == "key_1" && v != "value_1") {
+               failed()
+       }
+       if (k == "key_2" && v != "value_2") {
+               failed()
+       }
+       if (k == "key_3" && v != "value_3") {
+               failed()
+       }
+}
+
+if (n != len(t)) {
+       failed()
+}
diff --git a/drivers/staging/ktap/test/run_test.sh b/drivers/staging/ktap/test/run_test.sh
new file mode 100644 (file)
index 0000000..b98af26
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+rmmod ktapvm > /dev/null 2>&1
+insmod ../ktapvm.ko
+if test $? -ne 0; then
+       echo "Cannot insmod ../ktapvm.ko"
+       exit -1
+fi
+
+KTAP=../ktap
+function ktaprun {
+       echo "$KTAP $@"
+       $KTAP $@
+}
+
+
+
+#######################################################
+# Use $ktap directly if the arguments contains strings
+$KTAP arg.kp 1 testing "2 3 4"
+$KTAP -e 'print("one-liner testing")'
+$KTAP -e 'exit()'
+$KTAP -o /dev/null -e 'trace syscalls:* { print(argevent) }' \
+               -- ls > /devnull
+
+$KTAP -o /dev/null -e 'trace syscalls:* { print(argevent) }' \
+               -- $KTAP -e 'while (1) {}'
+
+ktaprun arith.kp
+ktaprun concat.kp
+ktaprun count.kp
+ktaprun fibonacci.kp
+ktaprun function.kp
+ktaprun if.kp
+ktaprun kprobe.kp
+ktaprun kretprobe.kp
+ktaprun len.kp
+ktaprun looping.kp
+ktaprun pairs.kp
+ktaprun table.kp
+ktaprun aggr_table.kp
+ktaprun timer.kp
+ktaprun tracepoint.kp
+ktaprun -o /dev/null zerodivide.kp
+ktaprun ansi.kp
+
+echo "testing kill deadloop ktap script"
+$KTAP -e 'while (1) {}' &
+pkill ktap
+sleep 1
+
+#####################################################
+rmmod ktapvm
+if test $? -ne 0; then
+       echo "Error in rmmod ../ktapvm.ko, leak module refcount?"
+       exit -1
+fi
+
diff --git a/drivers/staging/ktap/test/table.kp b/drivers/staging/ktap/test/table.kp
new file mode 100644 (file)
index 0000000..1f6d6e4
--- /dev/null
@@ -0,0 +1,71 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+### table testing ###
+x = {}
+x[1] = "1"
+if (x[1] != "1") {
+       failed()
+}
+
+x[1] = 22222222222222222222222222222222222222222
+if (x[1] != 22222222222222222222222222222222222222222) {
+       failed()
+}
+
+x[1] = "jovi"
+if (x[1] != "jovi") {
+       failed()
+}
+
+x[11111111111111111111111111111111] = "jovi"
+if (x[11111111111111111111111111111111] != "jovi") {
+       failed()
+}
+
+x["jovi"] = 1
+if (x["jovi"] != 1) {
+       failed()
+}
+
+x["long string....................................."] = 1
+if (x["long string....................................."] != 1) {
+       failed()
+}
+
+# issue: subx must declare firstly, otherwise kernel will oops
+subx = {}
+subx["test"] = "this is test"
+x["test"] = subx
+if (x["test"]["test"] != "this is test") {
+       failed()
+}
+
+tbl = {}
+i = 1
+while (i < 100000) {
+       tbl[i] = i      
+       i = i + 1
+}
+
+i = 1
+while (i < 100000) {
+       if (tbl[i] != i) {
+               failed()
+       }
+       i = i + 1
+}
+
+#### table initization
+days = {"Sunday", "Monday", "Tuesday", "Wednesday",
+       "Thursday", "Friday", "Saturday"}
+
+if (days[2] != "Monday") {
+       failed()
+}
+
+
diff --git a/drivers/staging/ktap/test/timer.kp b/drivers/staging/ktap/test/timer.kp
new file mode 100644 (file)
index 0000000..02e8a61
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#---------------------------------------#
+
+n1 = 0
+n2 = 0
+
+tick-1s {
+       n1 = n1 + 1
+}
+
+tick-1s {
+       n2 = n2 + 1
+}
+
+tick-4s {
+       if (n1 == 0 || n2 == 0) {
+               failed()
+       }
+       exit()
+}
+
+
diff --git a/drivers/staging/ktap/test/tracepoint.kp b/drivers/staging/ktap/test/tracepoint.kp
new file mode 100644 (file)
index 0000000..fb036e6
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/env ktap
+
+function failed() {
+       printf("failed\n");
+       exit(-1);
+}
+
+#----------------------------------------#
+
+n = 0
+
+trace sched:* {
+       n = n + 1
+}
+
+tick-1s {
+       if (n == 0) {
+               failed()
+       }
+       exit()
+}
+
diff --git a/drivers/staging/ktap/test/zerodivide.kp b/drivers/staging/ktap/test/zerodivide.kp
new file mode 100644 (file)
index 0000000..abb1eae
--- /dev/null
@@ -0,0 +1,5 @@
+#!/usr/bin/env ktap
+
+a = 1/0
+#should not go here
+printf("Failed\n")
diff --git a/drivers/staging/ktap/userspace/code.c b/drivers/staging/ktap/userspace/code.c
new file mode 100644 (file)
index 0000000..1427fd5
--- /dev/null
@@ -0,0 +1,968 @@
+/*
+ * code.c - Code generator for ktap
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../include/ktap_types.h"
+#include "../include/ktap_opcodes.h"
+#include "ktapc.h"
+
+
+#define hasjumps(e)    ((e)->t != (e)->f)
+
+void codegen_patchtohere (ktap_funcstate *fs, int list);
+
+static int isnumeral(ktap_expdesc *e)
+{
+       return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
+}
+
+void codegen_nil(ktap_funcstate *fs, int from, int n)
+{
+       ktap_instruction *previous;
+       int l = from + n - 1;  /* last register to set nil */
+
+       if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
+               previous = &fs->f->code[fs->pc-1];
+               if (GET_OPCODE(*previous) == OP_LOADNIL) {
+                       int pfrom = GETARG_A(*previous);
+                       int pl = pfrom + GETARG_B(*previous);
+
+                       if ((pfrom <= from && from <= pl + 1) ||
+                               (from <= pfrom && pfrom <= l + 1)) {  /* can connect both? */
+                               if (pfrom < from)
+                                       from = pfrom;  /* from = min(from, pfrom) */
+                               if (pl > l)
+                                       l = pl;  /* l = max(l, pl) */
+                               SETARG_A(*previous, from);
+                               SETARG_B(*previous, l - from);
+                               return;
+                       }
+               }  /* else go through */
+       }
+       codegen_codeABC(fs, OP_LOADNIL, from, n - 1, 0);  /* else no optimization */
+}
+
+int codegen_jump(ktap_funcstate *fs)
+{
+       int jpc = fs->jpc;  /* save list of jumps to here */
+       int j;
+
+       fs->jpc = NO_JUMP;
+       j = codegen_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
+       codegen_concat(fs, &j, jpc);  /* keep them on hold */
+       return j;
+}
+
+void codegen_ret(ktap_funcstate *fs, int first, int nret)
+{
+       codegen_codeABC(fs, OP_RETURN, first, nret+1, 0);
+}
+
+static int condjump(ktap_funcstate *fs, OpCode op, int A, int B, int C)
+{
+       codegen_codeABC(fs, op, A, B, C);
+       return codegen_jump(fs);
+}
+
+static void fixjump(ktap_funcstate *fs, int pc, int dest)
+{
+       ktap_instruction *jmp = &fs->f->code[pc];
+       int offset = dest-(pc+1);
+
+       ktap_assert(dest != NO_JUMP);
+       if (abs(offset) > MAXARG_sBx)
+               lex_syntaxerror(fs->ls, "control structure too long");
+       SETARG_sBx(*jmp, offset);
+}
+
+/*
+ * returns current `pc' and marks it as a jump target (to avoid wrong
+ * optimizations with consecutive instructions not in the same basic block).
+ */
+int codegen_getlabel(ktap_funcstate *fs)
+{
+       fs->lasttarget = fs->pc;
+       return fs->pc;
+}
+
+static int getjump(ktap_funcstate *fs, int pc)
+{
+       int offset = GETARG_sBx(fs->f->code[pc]);
+
+       if (offset == NO_JUMP)  /* point to itself represents end of list */
+               return NO_JUMP;  /* end of list */
+       else
+               return (pc+1)+offset;  /* turn offset into absolute position */
+}
+
+static ktap_instruction *getjumpcontrol(ktap_funcstate *fs, int pc)
+{
+       ktap_instruction *pi = &fs->f->code[pc];
+       if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
+               return pi-1;
+       else
+               return pi;
+}
+
+/*
+ * check whether list has any jump that do not produce a value
+ * (or produce an inverted value)
+ */
+static int need_value(ktap_funcstate *fs, int list)
+{
+       for (; list != NO_JUMP; list = getjump(fs, list)) {
+               ktap_instruction i = *getjumpcontrol(fs, list);
+               if (GET_OPCODE(i) != OP_TESTSET)
+                       return 1;
+       }
+       return 0;  /* not found */
+}
+
+static int patchtestreg(ktap_funcstate *fs, int node, int reg)
+{
+       ktap_instruction *i = getjumpcontrol(fs, node);
+       if (GET_OPCODE(*i) != OP_TESTSET)
+               return 0;  /* cannot patch other instructions */
+       if (reg != NO_REG && reg != GETARG_B(*i))
+               SETARG_A(*i, reg);
+       else  /* no register to put value or register already has the value */
+               *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
+
+       return 1;
+}
+
+static void removevalues(ktap_funcstate *fs, int list)
+{
+       for (; list != NO_JUMP; list = getjump(fs, list))
+               patchtestreg(fs, list, NO_REG);
+}
+
+static void patchlistaux(ktap_funcstate *fs, int list, int vtarget, int reg,
+                        int dtarget)
+{
+       while (list != NO_JUMP) {
+               int next = getjump(fs, list);
+               if (patchtestreg(fs, list, reg))
+                       fixjump(fs, list, vtarget);
+               else
+                       fixjump(fs, list, dtarget);  /* jump to default target */
+               list = next;
+       }
+}
+
+static void dischargejpc(ktap_funcstate *fs)
+{
+       patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
+       fs->jpc = NO_JUMP;
+}
+
+void codegen_patchlist(ktap_funcstate *fs, int list, int target)
+{
+       if (target == fs->pc)
+               codegen_patchtohere(fs, list);
+       else {
+               ktap_assert(target < fs->pc);
+               patchlistaux(fs, list, target, NO_REG, target);
+       }
+}
+
+void codegen_patchclose(ktap_funcstate *fs, int list, int level)
+{
+       level++;  /* argument is +1 to reserve 0 as non-op */
+       while (list != NO_JUMP) {
+               int next = getjump(fs, list);
+               ktap_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
+                          (GETARG_A(fs->f->code[list]) == 0 ||
+                           GETARG_A(fs->f->code[list]) >= level));
+               SETARG_A(fs->f->code[list], level);
+               list = next;
+       }
+}
+
+void codegen_patchtohere(ktap_funcstate *fs, int list)
+{
+       codegen_getlabel(fs);
+       codegen_concat(fs, &fs->jpc, list);
+}
+
+void codegen_concat(ktap_funcstate *fs, int *l1, int l2)
+{
+       if (l2 == NO_JUMP)
+               return;
+       else if (*l1 == NO_JUMP)
+               *l1 = l2;
+       else {
+               int list = *l1;
+               int next;
+               while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
+                       list = next;
+               fixjump(fs, list, l2);
+       }
+}
+
+static int codegen_code(ktap_funcstate *fs, ktap_instruction i)
+{
+       ktap_proto *f = fs->f;
+
+       dischargejpc(fs);  /* `pc' will change */
+
+       /* put new instruction in code array */
+       ktapc_growvector(f->code, fs->pc, f->sizecode, ktap_instruction,
+                        MAX_INT, "opcodes");
+       f->code[fs->pc] = i;
+
+       /* save corresponding line information */
+       ktapc_growvector(f->lineinfo, fs->pc, f->sizelineinfo, int,
+                        MAX_INT, "opcodes");
+       f->lineinfo[fs->pc] = fs->ls->lastline;
+       return fs->pc++;
+}
+
+int codegen_codeABC(ktap_funcstate *fs, OpCode o, int a, int b, int c)
+{
+       ktap_assert(getOpMode(o) == iABC);
+       //ktap_assert(getBMode(o) != OpArgN || b == 0);
+       //ktap_assert(getCMode(o) != OpArgN || c == 0);
+       //ktap_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
+       return codegen_code(fs, CREATE_ABC(o, a, b, c));
+}
+
+int codegen_codeABx(ktap_funcstate *fs, OpCode o, int a, unsigned int bc)
+{
+       ktap_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
+       ktap_assert(getCMode(o) == OpArgN);
+       ktap_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
+       return codegen_code(fs, CREATE_ABx(o, a, bc));
+}
+
+static int codeextraarg(ktap_funcstate *fs, int a)
+{
+       ktap_assert(a <= MAXARG_Ax);
+       return codegen_code(fs, CREATE_Ax(OP_EXTRAARG, a));
+}
+
+int codegen_codek(ktap_funcstate *fs, int reg, int k)
+{
+       if (k <= MAXARG_Bx)
+               return codegen_codeABx(fs, OP_LOADK, reg, k);
+       else {
+               int p = codegen_codeABx(fs, OP_LOADKX, reg, 0);
+               codeextraarg(fs, k);
+               return p;
+       }
+}
+
+void codegen_checkstack(ktap_funcstate *fs, int n)
+{
+       int newstack = fs->freereg + n;
+
+       if (newstack > fs->f->maxstacksize) {
+               if (newstack >= MAXSTACK)
+                       lex_syntaxerror(fs->ls, "function or expression too complex");
+               fs->f->maxstacksize = (u8)(newstack);
+       }
+}
+
+void codegen_reserveregs(ktap_funcstate *fs, int n)
+{
+       codegen_checkstack(fs, n);
+       fs->freereg += n;
+}
+
+static void freereg(ktap_funcstate *fs, int reg)
+{
+       if (!ISK(reg) && reg >= fs->nactvar) {
+               fs->freereg--;
+               ktap_assert(reg == fs->freereg);
+       }
+}
+
+static void freeexp(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       if (e->k == VNONRELOC)
+               freereg(fs, e->u.info);
+}
+
+static int addk(ktap_funcstate *fs, ktap_value *key, ktap_value *v)
+{
+       const ktap_value *idx = ktapc_table_get(fs->h, key);
+       ktap_proto *f = fs->f;
+       ktap_value kn;
+       int k, oldsize;
+
+       if (ttisnumber(idx)) {
+               ktap_number n = nvalue(idx);
+               ktap_number2int(k, n);
+               if (ktapc_equalobj(&f->k[k], v))
+                       return k;
+               /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
+                       go through and create a new entry for this value */
+       }
+       /* constant not found; create a new entry */
+       oldsize = f->sizek;
+       k = fs->nk;
+
+       /* numerical value does not need GC barrier;
+          table has no metatable, so it does not need to invalidate cache */
+       setnvalue(&kn, (ktap_number)k);
+       ktapc_table_setvalue(fs->h, key, &kn);
+       ktapc_growvector(f->k, k, f->sizek, ktap_value, MAXARG_Ax, "constants");
+       while (oldsize < f->sizek)
+               setnilvalue(&f->k[oldsize++]);
+       setobj(&f->k[k], v);
+       fs->nk++;
+       return k;
+}
+
+int codegen_stringK(ktap_funcstate *fs, ktap_string *s)
+{
+       ktap_value o;
+
+       setsvalue(&o, s);
+       return addk(fs, &o, &o);
+}
+
+int codegen_numberK(ktap_funcstate *fs, ktap_number r)
+{
+       int n;
+       ktap_value o, s;
+
+       setnvalue(&o, r);
+       if (r == 0 || ktap_numisnan(NULL, r)) {  /* handle -0 and NaN */
+               /* use raw representation as key to avoid numeric problems */
+               setsvalue(&s, ktapc_ts_newlstr((char *)&r, sizeof(r)));
+               //   incr_top(L);
+               n = addk(fs, &s, &o);
+               //   L->top--;
+       } else
+               n = addk(fs, &o, &o);  /* regular case */
+       return n;
+}
+
+static int boolK(ktap_funcstate *fs, int b)
+{
+       ktap_value o;
+       setbvalue(&o, b);
+       return addk(fs, &o, &o);
+}
+
+static int nilK(ktap_funcstate *fs)
+{
+       ktap_value k, v;
+       setnilvalue(&v);
+       /* cannot use nil as key; instead use table itself to represent nil */
+       sethvalue(&k, fs->h);
+       return addk(fs, &k, &v);
+}
+
+void codegen_setreturns(ktap_funcstate *fs, ktap_expdesc *e, int nresults)
+{
+       if (e->k == VCALL) {  /* expression is an open function call? */
+               SETARG_C(getcode(fs, e), nresults+1);
+       }
+       else if (e->k == VVARARG) {
+               SETARG_B(getcode(fs, e), nresults+1);
+               SETARG_A(getcode(fs, e), fs->freereg);
+               codegen_reserveregs(fs, 1);
+       }
+}
+
+void codegen_setoneret(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       if (e->k == VCALL) {  /* expression is an open function call? */
+               e->k = VNONRELOC;
+               e->u.info = GETARG_A(getcode(fs, e));
+       } else if (e->k == VVARARG) {
+               SETARG_B(getcode(fs, e), 2);
+               e->k = VRELOCABLE;  /* can relocate its simple result */
+       }
+}
+
+void codegen_dischargevars(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       switch (e->k) {
+       case VLOCAL: {
+               e->k = VNONRELOC;
+               break;
+       }
+       case VUPVAL: {
+               e->u.info = codegen_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
+               e->k = VRELOCABLE;
+               break;
+       }
+       case VINDEXED: {
+               OpCode op = OP_GETTABUP;  /* assume 't' is in an upvalue */
+               freereg(fs, e->u.ind.idx);
+               if (e->u.ind.vt == VLOCAL) {  /* 't' is in a register? */
+                       freereg(fs, e->u.ind.t);
+                       op = OP_GETTABLE;
+               }
+               e->u.info = codegen_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
+               e->k = VRELOCABLE;
+               break;
+       }
+       case VVARARG:
+       case VCALL: {
+               codegen_setoneret(fs, e);
+               break;
+       }
+       default:
+               break;  /* there is one value available (somewhere) */
+       }
+}
+
+static int code_label(ktap_funcstate *fs, int A, int b, int jump)
+{
+       codegen_getlabel(fs);  /* those instructions may be jump targets */
+       return codegen_codeABC(fs, OP_LOADBOOL, A, b, jump);
+}
+
+static void discharge2reg(ktap_funcstate *fs, ktap_expdesc *e, int reg)
+{
+       codegen_dischargevars(fs, e);
+       switch (e->k) {
+       case VNIL: {
+               codegen_nil(fs, reg, 1);
+               break;
+       }
+       case VFALSE:  case VTRUE: {
+               codegen_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
+               break;
+       }
+       case VEVENT:
+               codegen_codeABC(fs, OP_EVENT, reg, 0, 0);
+               break;
+       case VEVENTNAME:
+               codegen_codeABC(fs, OP_EVENTNAME, reg, 0, 0);
+               break;
+       case VEVENTARG:
+               codegen_codeABC(fs, OP_EVENTARG, reg, e->u.info, 0);
+               break;
+       case VK: {
+               codegen_codek(fs, reg, e->u.info);
+               break;
+       }
+       case VKNUM: {
+               codegen_codek(fs, reg, codegen_numberK(fs, e->u.nval));
+               break;
+       }
+       case VRELOCABLE: {
+               ktap_instruction *pc = &getcode(fs, e);
+               SETARG_A(*pc, reg);
+               break;
+       }
+       case VNONRELOC: {
+               if (reg != e->u.info)
+                       codegen_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
+               break;
+       }
+       default:
+               ktap_assert(e->k == VVOID || e->k == VJMP);
+               return;  /* nothing to do... */
+       }
+
+       e->u.info = reg;
+       e->k = VNONRELOC;
+}
+
+static void discharge2anyreg(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       if (e->k != VNONRELOC) {
+               codegen_reserveregs(fs, 1);
+               discharge2reg(fs, e, fs->freereg-1);
+       }
+}
+
+static void exp2reg(ktap_funcstate *fs, ktap_expdesc *e, int reg)
+{
+       discharge2reg(fs, e, reg);
+       if (e->k == VJMP)
+               codegen_concat(fs, &e->t, e->u.info);  /* put this jump in `t' list */
+       if (hasjumps(e)) {
+               int final;  /* position after whole expression */
+               int p_f = NO_JUMP;  /* position of an eventual LOAD false */
+               int p_t = NO_JUMP;  /* position of an eventual LOAD true */
+
+               if (need_value(fs, e->t) || need_value(fs, e->f)) {
+                       int fj = (e->k == VJMP) ? NO_JUMP : codegen_jump(fs);
+
+                       p_f = code_label(fs, reg, 0, 1);
+                       p_t = code_label(fs, reg, 1, 0);
+                       codegen_patchtohere(fs, fj);
+               }
+               final = codegen_getlabel(fs);
+               patchlistaux(fs, e->f, final, reg, p_f);
+               patchlistaux(fs, e->t, final, reg, p_t);
+       }
+       e->f = e->t = NO_JUMP;
+       e->u.info = reg;
+       e->k = VNONRELOC;
+}
+
+void codegen_exp2nextreg(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       codegen_dischargevars(fs, e);
+       freeexp(fs, e);
+       codegen_reserveregs(fs, 1);
+       exp2reg(fs, e, fs->freereg - 1);
+}
+
+int codegen_exp2anyreg(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       codegen_dischargevars(fs, e);
+       if (e->k == VNONRELOC) {
+               if (!hasjumps(e))
+                       return e->u.info;  /* exp is already in a register */
+               if (e->u.info >= fs->nactvar) {  /* reg. is not a local? */
+                       exp2reg(fs, e, e->u.info);  /* put value on it */
+                       return e->u.info;
+               }
+       }
+       codegen_exp2nextreg(fs, e);  /* default */
+       return e->u.info;
+}
+
+void codegen_exp2anyregup(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       if (e->k != VUPVAL || hasjumps(e))
+               codegen_exp2anyreg(fs, e);
+}
+
+void codegen_exp2val(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       if (hasjumps(e))
+               codegen_exp2anyreg(fs, e);
+       else
+               codegen_dischargevars(fs, e);
+}
+
+int codegen_exp2RK(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       codegen_exp2val(fs, e);
+       switch (e->k) {
+       case VTRUE:
+       case VFALSE:
+       case VNIL: {
+               if (fs->nk <= MAXINDEXRK) {  /* constant fits in RK operand? */
+                       e->u.info = (e->k == VNIL) ? nilK(fs) :
+                                                    boolK(fs, (e->k == VTRUE));
+                       e->k = VK;
+                       return RKASK(e->u.info);
+               }
+               else
+                       break;
+       }
+       case VKNUM: {
+               e->u.info = codegen_numberK(fs, e->u.nval);
+               e->k = VK;
+               /* go through */
+       }
+       case VK: {
+               if (e->u.info <= MAXINDEXRK)  /* constant fits in argC? */
+                       return RKASK(e->u.info);
+               else
+                       break;
+       }
+       default:
+               break;
+       }
+       /* not a constant in the right range: put it in a register */
+       return codegen_exp2anyreg(fs, e);
+}
+
+void codegen_storevar(ktap_funcstate *fs, ktap_expdesc *var, ktap_expdesc *ex)
+{
+       switch (var->k) {
+       case VLOCAL: {
+               freeexp(fs, ex);
+               exp2reg(fs, ex, var->u.info);
+               return;
+       }
+       case VUPVAL: {
+               int e = codegen_exp2anyreg(fs, ex);
+               codegen_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
+               break;
+       }
+       case VINDEXED: {
+               OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
+               int e = codegen_exp2RK(fs, ex);
+               codegen_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
+               break;
+       }
+       default:
+               ktap_assert(0);  /* invalid var kind to store */
+               break;
+       }
+
+       freeexp(fs, ex);
+}
+
+void codegen_storeincr(ktap_funcstate *fs, ktap_expdesc *var, ktap_expdesc *ex)
+{
+       switch (var->k) {
+#if 0 /*current not supported */
+       case VLOCAL: {
+               freeexp(fs, ex);
+               exp2reg(fs, ex, var->u.info);
+               return;
+       }
+       case VUPVAL: {
+               int e = codegen_exp2anyreg(fs, ex);
+               codegen_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
+               break;
+       }
+#endif
+       case VINDEXED: {
+               OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE_INCR :
+                               OP_SETTABUP_INCR;
+               int e = codegen_exp2RK(fs, ex);
+               codegen_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
+               break;
+       }
+       default:
+               ktap_assert(0);  /* invalid var kind to store */
+               break;
+       }
+
+       freeexp(fs, ex);
+}
+
+
+void codegen_self(ktap_funcstate *fs, ktap_expdesc *e, ktap_expdesc *key)
+{
+       int ereg;
+
+       codegen_exp2anyreg(fs, e);
+       ereg = e->u.info;  /* register where 'e' was placed */
+       freeexp(fs, e);
+       e->u.info = fs->freereg;  /* base register for op_self */
+       e->k = VNONRELOC;
+       codegen_reserveregs(fs, 2);  /* function and 'self' produced by op_self */
+       codegen_codeABC(fs, OP_SELF, e->u.info, ereg, codegen_exp2RK(fs, key));
+       freeexp(fs, key);
+}
+
+static void invertjump(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       ktap_instruction *pc = getjumpcontrol(fs, e->u.info);
+       ktap_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
+                       GET_OPCODE(*pc) != OP_TEST);
+       SETARG_A(*pc, !(GETARG_A(*pc)));
+}
+
+static int jumponcond(ktap_funcstate *fs, ktap_expdesc *e, int cond)
+{
+       if (e->k == VRELOCABLE) {
+               ktap_instruction ie = getcode(fs, e);
+               if (GET_OPCODE(ie) == OP_NOT) {
+                       fs->pc--;  /* remove previous OP_NOT */
+                       return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
+               }
+               /* else go through */
+       }
+       discharge2anyreg(fs, e);
+       freeexp(fs, e);
+       return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
+}
+
+void codegen_goiftrue(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       int pc;  /* pc of last jump */
+
+       codegen_dischargevars(fs, e);
+       switch (e->k) {
+       case VJMP: {
+               invertjump(fs, e);
+               pc = e->u.info;
+               break;
+       }
+       case VK: case VKNUM: case VTRUE: {
+               pc = NO_JUMP;  /* always true; do nothing */
+               break;
+       }
+       default:
+               pc = jumponcond(fs, e, 0);
+               break;
+       }
+
+       codegen_concat(fs, &e->f, pc);  /* insert last jump in `f' list */
+       codegen_patchtohere(fs, e->t);
+       e->t = NO_JUMP;
+}
+
+void codegen_goiffalse(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       int pc;  /* pc of last jump */
+       codegen_dischargevars(fs, e);
+
+       switch (e->k) {
+       case VJMP: {
+               pc = e->u.info;
+               break;
+       }
+       case VNIL: case VFALSE: {
+               pc = NO_JUMP;  /* always false; do nothing */
+               break;
+       }
+       default:
+               pc = jumponcond(fs, e, 1);
+               break;
+       }
+       codegen_concat(fs, &e->t, pc);  /* insert last jump in `t' list */
+       codegen_patchtohere(fs, e->f);
+       e->f = NO_JUMP;
+}
+
+static void codenot(ktap_funcstate *fs, ktap_expdesc *e)
+{
+       codegen_dischargevars(fs, e);
+       switch (e->k) {
+       case VNIL: case VFALSE: {
+               e->k = VTRUE;
+               break;
+       }
+       case VK: case VKNUM: case VTRUE: {
+               e->k = VFALSE;
+               break;
+       }
+       case VJMP: {
+               invertjump(fs, e);
+               break;
+       }
+       case VRELOCABLE:
+       case VNONRELOC: {
+               discharge2anyreg(fs, e);
+               freeexp(fs, e);
+               e->u.info = codegen_codeABC(fs, OP_NOT, 0, e->u.info, 0);
+               e->k = VRELOCABLE;
+               break;
+       }
+       default:
+               ktap_assert(0);  /* cannot happen */
+               break;
+       }
+
+       /* interchange true and false lists */
+       { int temp = e->f; e->f = e->t; e->t = temp; }
+       removevalues(fs, e->f);
+       removevalues(fs, e->t);
+}
+
+void codegen_indexed(ktap_funcstate *fs, ktap_expdesc *t, ktap_expdesc *k)
+{
+       ktap_assert(!hasjumps(t));
+       t->u.ind.t = t->u.info;
+       t->u.ind.idx = codegen_exp2RK(fs, k);
+       t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
+                       : check_exp(vkisinreg(t->k), VLOCAL);
+       t->k = VINDEXED;
+}
+
+static int constfolding(OpCode op, ktap_expdesc *e1, ktap_expdesc *e2)
+{
+       ktap_number r;
+
+       if (!isnumeral(e1) || !isnumeral(e2))
+               return 0;
+
+       if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
+               return 0;  /* do not attempt to divide by 0 */
+
+       if (op == OP_POW)
+               return 0; /* ktap current do not suppor pow arith */
+
+       r = ktapc_arith(op - OP_ADD + KTAP_OPADD, e1->u.nval, e2->u.nval);
+       e1->u.nval = r;
+       return 1;
+}
+
+static void codearith(ktap_funcstate *fs, OpCode op,
+                     ktap_expdesc *e1, ktap_expdesc *e2, int line)
+{
+       if (constfolding(op, e1, e2))
+               return;
+       else {
+               int o2 = (op != OP_UNM && op != OP_LEN) ? codegen_exp2RK(fs, e2) : 0;
+               int o1 = codegen_exp2RK(fs, e1);
+
+               if (o1 > o2) {
+                       freeexp(fs, e1);
+                       freeexp(fs, e2);
+               } else {
+                       freeexp(fs, e2);
+                       freeexp(fs, e1);
+               }
+               e1->u.info = codegen_codeABC(fs, op, 0, o1, o2);
+               e1->k = VRELOCABLE;
+               codegen_fixline(fs, line);
+       }
+}
+
+static void codecomp(ktap_funcstate *fs, OpCode op, int cond, ktap_expdesc *e1,
+                    ktap_expdesc *e2)
+{
+       int o1 = codegen_exp2RK(fs, e1);
+       int o2 = codegen_exp2RK(fs, e2);
+
+       freeexp(fs, e2);
+       freeexp(fs, e1);
+       if (cond == 0 && op != OP_EQ) {
+               int temp;  /* exchange args to replace by `<' or `<=' */
+               temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
+               cond = 1;
+       }
+       e1->u.info = condjump(fs, op, cond, o1, o2);
+       e1->k = VJMP;
+}
+
+void codegen_prefix(ktap_funcstate *fs, UnOpr op, ktap_expdesc *e, int line)
+{
+       ktap_expdesc e2;
+
+       e2.t = e2.f = NO_JUMP;
+       e2.k = VKNUM;
+       e2.u.nval = 0;
+
+       switch (op) {
+       case OPR_MINUS: {
+               if (isnumeral(e))  /* minus constant? */
+                       e->u.nval = ktap_numunm(e->u.nval);  /* fold it */
+               else {
+                       codegen_exp2anyreg(fs, e);
+                       codearith(fs, OP_UNM, e, &e2, line);
+               }
+               break;
+       }
+       case OPR_NOT:
+               codenot(fs, e);
+               break;
+       case OPR_LEN: {
+               codegen_exp2anyreg(fs, e);  /* cannot operate on constants */
+               codearith(fs, OP_LEN, e, &e2, line);
+               break;
+       }
+       default:
+               ktap_assert(0);
+       }
+}
+
+void codegen_infix(ktap_funcstate *fs, BinOpr op, ktap_expdesc *v)
+{
+       switch (op) {
+       case OPR_AND: {
+               codegen_goiftrue(fs, v);
+               break;
+       }
+       case OPR_OR: {
+               codegen_goiffalse(fs, v);
+               break;
+       }
+       case OPR_CONCAT: {
+               codegen_exp2nextreg(fs, v);  /* operand must be on the `stack' */
+               break;
+       }
+       case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
+       case OPR_MOD: case OPR_POW: {
+               if (!isnumeral(v)) codegen_exp2RK(fs, v);
+                       break;
+       }
+       default:
+               codegen_exp2RK(fs, v);
+               break;
+       }
+}
+
+void codegen_posfix(ktap_funcstate *fs, BinOpr op, ktap_expdesc *e1, ktap_expdesc *e2, int line)
+{
+       switch (op) {
+       case OPR_AND: {
+               ktap_assert(e1->t == NO_JUMP);  /* list must be closed */
+               codegen_dischargevars(fs, e2);
+               codegen_concat(fs, &e2->f, e1->f);
+               *e1 = *e2;
+               break;
+       }
+       case OPR_OR: {
+               ktap_assert(e1->f == NO_JUMP);  /* list must be closed */
+               codegen_dischargevars(fs, e2);
+               codegen_concat(fs, &e2->t, e1->t);
+               *e1 = *e2;
+               break;
+       }
+       case OPR_CONCAT: {
+               codegen_exp2val(fs, e2);
+               if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
+                       ktap_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
+                       freeexp(fs, e1);
+                       SETARG_B(getcode(fs, e2), e1->u.info);
+                       e1->k = VRELOCABLE; e1->u.info = e2->u.info;
+               } else {
+                       codegen_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
+                       codearith(fs, OP_CONCAT, e1, e2, line);
+               }
+               break;
+       }
+       case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
+       case OPR_MOD: case OPR_POW: {
+               codearith(fs, (OpCode)(op - OPR_ADD + OP_ADD), e1, e2, line);
+               break;
+       }
+       case OPR_EQ: case OPR_LT: case OPR_LE: {
+               codecomp(fs, (OpCode)(op - OPR_EQ + OP_EQ), 1, e1, e2);
+               break;
+       }
+       case OPR_NE: case OPR_GT: case OPR_GE: {
+               codecomp(fs, (OpCode)(op - OPR_NE + OP_EQ), 0, e1, e2);
+               break;
+       }
+       default:
+               ktap_assert(0);
+       }
+}
+
+void codegen_fixline(ktap_funcstate *fs, int line)
+{
+       fs->f->lineinfo[fs->pc - 1] = line;
+}
+
+void codegen_setlist(ktap_funcstate *fs, int base, int nelems, int tostore)
+{
+       int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
+       int b = (tostore == KTAP_MULTRET) ? 0 : tostore;
+
+       ktap_assert(tostore != 0);
+       if (c <= MAXARG_C)
+               codegen_codeABC(fs, OP_SETLIST, base, b, c);
+       else if (c <= MAXARG_Ax) {
+               codegen_codeABC(fs, OP_SETLIST, base, b, 0);
+               codeextraarg(fs, c);
+       } else
+               lex_syntaxerror(fs->ls, "constructor too long");
+       fs->freereg = base + 1;  /* free registers with list values */
+}
+
diff --git a/drivers/staging/ktap/userspace/dump.c b/drivers/staging/ktap/userspace/dump.c
new file mode 100644 (file)
index 0000000..088b08d
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * dump.c - save precompiled ktap chunks
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../include/ktap_types.h"
+#include "../include/ktap_opcodes.h"
+#include "ktapc.h"
+
+
+typedef struct {
+       ktap_writer writer;
+       void *data;
+       int strip;
+       int status;
+} DumpState;
+
+#define DumpMem(b, n, size, D) DumpBlock(b, (n)*(size), D)
+#define DumpVar(x, D)          DumpMem(&x, 1, sizeof(x), D)
+
+static void DumpBlock(const void *b, size_t size, DumpState *D)
+{
+       if (D->status == 0)
+               D->status = ((D->writer))(b, size, D->data);
+}
+
+static void DumpChar(int y, DumpState *D)
+{
+       char x = (char)y;
+       DumpVar(x, D);
+}
+
+static void DumpInt(int x, DumpState *D)
+{
+       DumpVar(x, D);
+}
+
+static void DumpNumber(ktap_number x, DumpState *D)
+{
+       DumpVar(x,D);
+}
+
+static void DumpVector(const void *b, int n, size_t size, DumpState *D)
+{
+       DumpInt(n, D);
+       DumpMem(b, n, size, D);
+}
+
+static void DumpString(const ktap_string *s, DumpState *D)
+{
+       if (s == NULL) {
+               int size = 0;
+               DumpVar(size, D);
+       } else {
+               int size = s->tsv.len + 1;              /* include trailing '\0' */
+               DumpVar(size, D);
+               DumpBlock(getstr(s), size * sizeof(char), D);
+       }
+}
+
+#define DumpCode(f, D)  DumpVector(f->code, f->sizecode, sizeof(ktap_instruction), D)
+
+static void DumpFunction(const ktap_proto *f, DumpState *D);
+
+static void DumpConstants(const ktap_proto *f, DumpState *D)
+{
+       int i, n = f->sizek;
+
+       DumpInt(n, D);
+       for (i = 0; i < n; i++) {
+               const ktap_value* o=&f->k[i];
+               DumpChar(ttypenv(o), D);
+               switch (ttypenv(o)) {
+               case KTAP_TNIL:
+                       break;
+               case KTAP_TBOOLEAN:
+                       DumpChar(bvalue(o), D);
+                       break;
+               case KTAP_TNUMBER:
+                       DumpNumber(nvalue(o), D);
+                       break;
+               case KTAP_TSTRING:
+                       DumpString(rawtsvalue(o), D);
+                       break;
+               default:
+                       printf("ktap: DumpConstants with unknown vaule type %d\n", ttypenv(o));
+                       ktap_assert(0);
+               }
+       }
+       n = f->sizep;
+       DumpInt(n, D);
+       for (i = 0; i < n; i++)
+               DumpFunction(f->p[i], D);
+}
+
+static void DumpUpvalues(const ktap_proto *f, DumpState *D)
+{
+       int i, n = f->sizeupvalues;
+
+       DumpInt(n, D);
+       for (i = 0; i < n; i++) {
+               DumpChar(f->upvalues[i].instack, D);
+               DumpChar(f->upvalues[i].idx, D);
+       }
+}
+
+static void DumpDebug(const ktap_proto *f, DumpState *D)
+{
+       int i,n;
+
+       DumpString((D->strip) ? NULL : f->source, D);
+       n= (D->strip) ? 0 : f->sizelineinfo;
+       DumpVector(f->lineinfo, n, sizeof(int), D);
+       n = (D->strip) ? 0 : f->sizelocvars;
+       DumpInt(n, D);
+
+       for (i = 0; i < n; i++) {
+               DumpString(f->locvars[i].varname, D);
+               DumpInt(f->locvars[i].startpc, D);
+               DumpInt(f->locvars[i].endpc, D);
+       }
+       n = (D->strip) ? 0 : f->sizeupvalues;
+       DumpInt(n, D);
+       for (i = 0; i < n; i++)
+               DumpString(f->upvalues[i].name, D);
+}
+
+static void DumpFunction(const ktap_proto *f, DumpState *D)
+{
+       DumpInt(f->linedefined, D);
+       DumpInt(f->lastlinedefined, D);
+       DumpChar(f->numparams, D);
+       DumpChar(f->is_vararg, D);
+       DumpChar(f->maxstacksize, D);
+       DumpCode(f, D);
+       DumpConstants(f, D);
+       DumpUpvalues(f, D);
+       DumpDebug(f, D);
+}
+
+static void DumpHeader(DumpState *D)
+{
+       u8 h[KTAPC_HEADERSIZE];
+
+       kp_header(h);
+       DumpBlock(h, KTAPC_HEADERSIZE, D);
+}
+
+/*
+ * dump ktap function as precompiled chunk
+ */
+int ktapc_dump(const ktap_proto *f, ktap_writer w, void *data, int strip)
+{
+       DumpState D;
+
+       D.writer = w;
+       D.data = data;
+       D.strip = strip;
+       D.status = 0;
+       DumpHeader(&D);
+       DumpFunction(f, &D);
+       return D.status;
+}
diff --git a/drivers/staging/ktap/userspace/eventdef.c b/drivers/staging/ktap/userspace/eventdef.c
new file mode 100644 (file)
index 0000000..76a68ac
--- /dev/null
@@ -0,0 +1,588 @@
+/*
+ * eventdef.c - ktap eventdef parser
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <fcntl.h>
+
+#include "../include/ktap_types.h"
+#include "../include/ktap_opcodes.h"
+#include "ktapc.h"
+
+static char tracing_events_path[] = "/sys/kernel/debug/tracing/events";
+
+#define IDS_ARRAY_SIZE 4096
+static u8 *ids_array;
+
+#define set_id(id)     \
+       do { \
+               ids_array[id/8] = ids_array[id/8] | (1 << (id%8));      \
+       } while(0)
+
+#define clear_id(id)   \
+       do { \
+               ids_array[id/8] = ids_array[id/8] & ~ (1 << (id%8));    \
+       } while(0)
+
+
+static int get_digit_len(int id)
+{
+       int len = -1;
+
+       if (id < 10)
+               len = 1;
+       else if (id < 100)
+               len = 2;
+       else if (id < 1000)
+               len = 3;
+       else if (id < 10000)
+               len = 4;
+       else if (id < 100000)
+               len = 5;
+
+       return len;
+}
+
+static char *get_idstr(char *filter)
+{
+       char *idstr, *ptr;
+       int total_len = 0;
+       int filter_len;
+       int i;
+
+       filter_len = filter ? strlen(filter) : 0;
+
+       for (i = 0; i < IDS_ARRAY_SIZE*8; i++) {
+               if (ids_array[i/8] & (1 << (i%8)))
+                       total_len += get_digit_len(i) + 1;
+       }
+
+       if (!total_len)
+               return NULL;
+
+       idstr = malloc(total_len + filter_len + 1);
+       if (!idstr)
+               return NULL;
+
+       memset(idstr, 0, total_len + filter_len + 1);
+       ptr = idstr;
+       for (i = 0; i < IDS_ARRAY_SIZE*8; i++) {
+               if (ids_array[i/8] & (1 << (i%8))) {
+                       char digits[32] = {0};
+                       int len;
+
+                       sprintf(digits, "%d ", i);
+                       len = strlen(digits);
+                       strncpy(ptr, digits, len);
+                       ptr += len;
+               }
+       }
+
+       if (filter)
+               memcpy(ptr, filter, strlen(filter));
+
+       return idstr;
+}
+
+static int add_event(char *evtid_path)
+{
+       char id_buf[24];
+       int id, fd;
+
+       fd = open(evtid_path, O_RDONLY);
+       if (fd < 0) {
+               /*
+                * some tracepoint doesn't have id file, like ftrace,
+                * return success in here, and don't print error.
+                */
+               verbose_printf("warning: cannot open file %s\n", evtid_path);
+               return 0;
+       }
+
+       if (read(fd, id_buf, sizeof(id_buf)) < 0) {
+               fprintf(stderr, "read file error %s\n", evtid_path);
+               close(fd);
+               return -1;
+       }
+
+       id = atoll(id_buf);
+
+       if (id >= IDS_ARRAY_SIZE * 8) {
+               fprintf(stderr, "tracepoint id(%d) is bigger than %d\n", id,
+                               IDS_ARRAY_SIZE * 8);
+               close(fd);
+               return -1;
+       }
+
+       set_id(id);
+
+       close(fd);
+       return 0;
+}
+
+static int add_tracepoint(char *sys_name, char *evt_name)
+{
+       char evtid_path[PATH_MAX] = {0};
+
+
+       snprintf(evtid_path, PATH_MAX, "%s/%s/%s/id", tracing_events_path,
+                                       sys_name, evt_name);
+       return add_event(evtid_path);
+}
+
+static int add_tracepoint_multi_event(char *sys_name, char *evt_name)
+{
+       char evt_path[PATH_MAX];
+       struct dirent *evt_ent;
+       DIR *evt_dir;
+       int ret = 0;
+
+       snprintf(evt_path, PATH_MAX, "%s/%s", tracing_events_path, sys_name);
+       evt_dir = opendir(evt_path);
+       if (!evt_dir) {
+               perror("Can't open event dir");
+               return -1;
+       }
+
+       while (!ret && (evt_ent = readdir(evt_dir))) {
+               if (!strcmp(evt_ent->d_name, ".")
+                   || !strcmp(evt_ent->d_name, "..")
+                   || !strcmp(evt_ent->d_name, "enable")
+                   || !strcmp(evt_ent->d_name, "filter"))
+                       continue;
+
+               if (!strglobmatch(evt_ent->d_name, evt_name))
+                       continue;
+
+               ret = add_tracepoint(sys_name, evt_ent->d_name);
+       }
+
+       closedir(evt_dir);
+       return ret;
+}
+
+static int add_tracepoint_event(char *sys_name, char *evt_name)
+{
+       return strpbrk(evt_name, "*?") ?
+              add_tracepoint_multi_event(sys_name, evt_name) :
+              add_tracepoint(sys_name, evt_name);
+}
+
+static int add_tracepoint_multi_sys(char *sys_name, char *evt_name)
+{
+       struct dirent *events_ent;
+       DIR *events_dir;
+       int ret = 0;
+
+       events_dir = opendir(tracing_events_path);
+       if (!events_dir) {
+               perror("Can't open event dir");
+               return -1;
+       }
+
+       while (!ret && (events_ent = readdir(events_dir))) {
+               if (!strcmp(events_ent->d_name, ".")
+                   || !strcmp(events_ent->d_name, "..")
+                   || !strcmp(events_ent->d_name, "enable")
+                   || !strcmp(events_ent->d_name, "header_event")
+                   || !strcmp(events_ent->d_name, "header_page"))
+                       continue;
+
+               if (!strglobmatch(events_ent->d_name, sys_name))
+                       continue;
+
+               ret = add_tracepoint_event(events_ent->d_name,
+                                          evt_name);
+       }
+
+       closedir(events_dir);
+       return ret;
+}
+
+static int parse_events_add_tracepoint(char *sys, char *event)
+{
+       if (strpbrk(sys, "*?"))
+               return add_tracepoint_multi_sys(sys, event);
+       else
+               return add_tracepoint_event(sys, event);
+}
+
+enum {
+       KPROBE_EVENT,
+       UPROBE_EVENT,
+};
+
+struct probe_list {
+       struct probe_list *next;
+       int type;
+       int kp_seq;
+       char *probe_event;
+};
+
+static struct probe_list *probe_list_head;
+
+#define KPROBE_EVENTS_PATH "/sys/kernel/debug/tracing/kprobe_events"
+
+static int parse_events_add_kprobe(char *old_event)
+{
+       static int event_seq = 0;
+       struct probe_list *pl;
+       char probe_event[128] = {0};
+       char event_id_path[128] = {0};
+       char *event;
+       char *r;
+       int fd;
+       int ret;
+
+       fd = open(KPROBE_EVENTS_PATH, O_WRONLY);
+       if (fd < 0) {
+               fprintf(stderr, "Cannot open %s\n", KPROBE_EVENTS_PATH);
+               return -1;
+       }
+
+       event = strdup(old_event);
+       r = strstr(event, "%return");
+       if (r) {
+               memset(r, ' ', 7);
+               snprintf(probe_event, 128, "r:kprobes/kp%d %s",
+                               event_seq, event);
+       } else
+               snprintf(probe_event, 128, "p:kprobes/kp%d %s",
+                               event_seq, event);
+
+       free(event);
+
+       verbose_printf("kprobe event %s\n", probe_event);
+       ret = write(fd, probe_event, strlen(probe_event));
+       if (ret <= 0) {
+               fprintf(stderr, "Cannot write %s to %s\n", probe_event,
+                               KPROBE_EVENTS_PATH);
+               close(fd);
+               return -1;
+       }
+
+       close(fd);
+
+       pl = malloc(sizeof(struct probe_list));
+       if (!pl)
+               return -1;
+
+       pl->type = KPROBE_EVENT;
+       pl->kp_seq = event_seq;
+       pl->next = probe_list_head;
+       probe_list_head = pl;
+
+       sprintf(event_id_path, "/sys/kernel/debug/tracing/events/kprobes/kp%d/id",
+                       event_seq);
+       ret = add_event(event_id_path);
+       if (ret < 0)
+               return -1;
+
+       event_seq++;
+       return 0;
+}
+
+#define UPROBE_EVENTS_PATH "/sys/kernel/debug/tracing/uprobe_events"
+
+static int parse_events_add_uprobe(char *old_event)
+{
+       static int event_seq = 0;
+       struct probe_list *pl;
+       char probe_event[128] = {0};
+       char event_id_path[128] = {0};
+       char *event;
+       char *r;
+       int fd;
+       int ret;
+
+       fd = open(UPROBE_EVENTS_PATH, O_WRONLY);
+       if (fd < 0) {
+               fprintf(stderr, "Cannot open %s\n", UPROBE_EVENTS_PATH);
+               return -1;
+       }
+
+       event = strdup(old_event);
+       r = strstr(event, "%return");
+       if (r) {
+               memset(r, ' ', 7);
+               snprintf(probe_event, 128, "r:uprobes/kp%d %s",
+                               event_seq, event);
+       } else
+               snprintf(probe_event, 128, "p:uprobes/kp%d %s",
+                               event_seq, event);
+
+       free(event);
+
+       verbose_printf("uprobe event %s\n", probe_event);
+       ret = write(fd, probe_event, strlen(probe_event));
+       if (ret <= 0) {
+               fprintf(stderr, "Cannot write %s to %s\n", probe_event,
+                               UPROBE_EVENTS_PATH);
+               close(fd);
+               return -1;
+       }
+
+       close(fd);
+
+       pl = malloc(sizeof(struct probe_list));
+       if (!pl)
+               return -1;
+
+       pl->type = UPROBE_EVENT;
+       pl->kp_seq = event_seq;
+       pl->next = probe_list_head;
+       probe_list_head = pl;
+
+       sprintf(event_id_path, "/sys/kernel/debug/tracing/events/uprobes/kp%d/id",
+                       event_seq);
+       ret = add_event(event_id_path);
+       if (ret < 0)
+               return -1;
+
+       event_seq++;
+       return 0;
+}
+
+static int parse_events_add_probe(char *old_event)
+{
+       char *separator;
+
+       separator = strchr(old_event, ':');
+       if (!separator || (separator == old_event))
+               return parse_events_add_kprobe(old_event);
+       else
+               return parse_events_add_uprobe(old_event);
+}
+
+static int parse_events_add_stapsdt(char *old_event)
+{
+       printf("Currently ktap don't support stapsdt, please waiting\n");
+
+       return -1;
+}
+
+static void strim(char *s)
+{
+       size_t size;
+       char *end;
+
+       size = strlen(s);
+       if (!size)
+               return;
+
+       end = s + size -1;
+       while (end >= s && isspace(*end))
+               end--;
+
+       *(end + 1) = '\0';
+}
+
+static int get_sys_event_filter_str(char *start,
+                                   char **sys, char **event, char **filter)
+{
+       char *separator, *separator2, *ptr, *end;
+
+       while (*start == ' ')
+               start++;
+
+       /* find sys */
+       separator = strchr(start, ':');
+       if (!separator || (separator == start)) {
+               return -1;
+       }
+
+       ptr = malloc(separator - start + 1);
+       if (!ptr)
+               return -1;
+
+       strncpy(ptr, start, separator - start);
+       ptr[separator - start] = '\0';
+
+       strim(ptr);
+       *sys = ptr;
+
+       if (!strcmp(*sys, "probe") && (*(separator + 1) == '/')) {
+               /* it's uprobe event */
+               separator2 = strchr(separator + 1, ':');
+               if (!separator2)
+                       return -1;
+       } else
+               separator2 = separator;
+
+       /* find filter */
+       end = start + strlen(start);
+       while (*--end == ' ') {
+       }
+
+       if (*end == '/') {
+               char *filter_start;
+
+               filter_start = strchr(separator2, '/');
+               if (filter_start == end)
+                       return -1;
+
+               ptr = malloc(end - filter_start + 2);
+               if (!ptr)
+                       return -1;
+
+               memcpy(ptr, filter_start, end - filter_start + 1);
+               ptr[end - filter_start + 1] = '\0';
+
+               *filter = ptr;
+
+               end = filter_start;
+       } else {
+               *filter = NULL;
+               end++;
+       }
+
+       /* find event */
+       ptr = malloc(end - separator);
+       if (!ptr)
+               return -1;
+
+       memcpy(ptr, separator + 1, end - separator - 1);
+       ptr[end - separator - 1] = '\0';
+
+       strim(ptr);
+       *event = ptr;
+
+       return 0;
+}
+
+static char *get_next_eventdef(char *str)
+{
+       char *separator;
+
+       separator = strchr(str, ',');
+       if (!separator)
+               return str + strlen(str);
+
+       *separator = '\0';
+       return separator + 1;
+}
+
+ktap_string *ktapc_parse_eventdef(ktap_string *eventdef)
+{
+       const char *def_str = getstr(eventdef);
+       char *str = strdup(def_str);
+       char *sys, *event, *filter, *idstr, *g_idstr, *next;
+       ktap_string *ts;
+       int ret;
+
+       if (!ids_array) {
+               ids_array = malloc(IDS_ARRAY_SIZE);
+               if (!ids_array)
+                       return NULL;
+       }
+
+       g_idstr = malloc(4096);
+       if (!g_idstr)
+               return NULL;
+
+       memset(g_idstr, 0, 4096);
+
+ parse_next_eventdef:
+       memset(ids_array, 0, IDS_ARRAY_SIZE);
+
+       next = get_next_eventdef(str);
+
+       if (get_sys_event_filter_str(str, &sys, &event, &filter))
+               goto error;
+
+       verbose_printf("parse_eventdef: sys[%s], event[%s], filter[%s]\n",
+                      sys, event, filter);
+
+       if (!strcmp(sys, "probe"))
+               ret = parse_events_add_probe(event);
+       else if (!strcmp(sys, "stapsdt"))
+               ret = parse_events_add_stapsdt(event);
+       else
+               ret = parse_events_add_tracepoint(sys, event);
+
+       if (ret)
+               goto error;
+
+       /* don't trace ftrace:function when all tracepoints enabled */
+       if (!strcmp(sys, "*"))
+               clear_id(1);
+
+       idstr = get_idstr(filter);
+       if (!idstr)
+               goto error;
+
+       str = next;
+
+       g_idstr = strcat(g_idstr, idstr);
+       g_idstr = strcat(g_idstr, ",");
+
+       if (*next != '\0')
+               goto parse_next_eventdef;
+
+       ts = ktapc_ts_new(g_idstr);
+       free(g_idstr);  
+
+       return ts;
+ error:
+       cleanup_event_resources();
+       return NULL;
+}
+
+void cleanup_event_resources(void)
+{
+       struct probe_list *pl;
+       const char *path;
+       char probe_event[32] = {0};
+       int fd, ret;
+
+       for (pl = probe_list_head; pl; pl = pl->next) {
+               if (pl->type == KPROBE_EVENT) {
+                       path = KPROBE_EVENTS_PATH;
+                       snprintf(probe_event, 32, "-:kprobes/kp%d", pl->kp_seq);
+               } else if (pl->type == UPROBE_EVENT) {
+                       path = UPROBE_EVENTS_PATH;
+                       snprintf(probe_event, 32, "-:uprobes/kp%d", pl->kp_seq);
+               } else {
+                       fprintf(stderr, "Cannot cleanup event type %d\n", pl->type);
+                       continue;
+               }
+
+               fd = open(path, O_WRONLY);
+               if (fd < 0) {
+                       fprintf(stderr, "Cannot open %s\n", UPROBE_EVENTS_PATH);
+                       continue;
+               }
+
+               ret = write(fd, probe_event, strlen(probe_event));
+               if (ret <= 0) {
+                       fprintf(stderr, "Cannot write %s to %s\n", probe_event,
+                                       path);
+                       close(fd);
+                       continue;
+               }
+
+               close(fd);
+       }
+}
+
diff --git a/drivers/staging/ktap/userspace/ktapc.h b/drivers/staging/ktap/userspace/ktapc.h
new file mode 100644 (file)
index 0000000..879cd29
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * ktapc.h
+ * only can be included by userspace compiler
+ */
+
+#include <ctype.h>
+
+typedef int bool;
+#define false 0
+#define true 1
+
+#define MAX_INT         ((int)(~0U>>1))
+#define UCHAR_MAX      255
+
+#define MAX_SIZET  ((size_t)(~(size_t)0)-2)
+
+#define KTAP_ERRSYNTAX 3
+
+/*
+ * KTAP_IDSIZE gives the maximum size for the description of the source
+ * of a function in debug information.
+ * CHANGE it if you want a different size.
+ */
+#define KTAP_IDSIZE      60
+
+
+#define FIRST_RESERVED  257
+
+/*
+ * maximum depth for nested C calls and syntactical nested non-terminals
+ * in a program. (Value must fit in an unsigned short int.)
+ */
+#define KTAP_MAXCCALLS          200
+
+#define KTAP_MULTRET     (-1)
+
+
+#define SHRT_MAX       UCHAR_MAX
+
+#define MAXUPVAL   UCHAR_MAX
+
+
+/* maximum stack for a ktap function */
+#define MAXSTACK        250
+
+#define islalpha(c)   (isalpha(c) || (c) == '_')
+#define islalnum(c)   (isalnum(c) || (c) == '_')
+
+#define isreserved(s) ((s)->tsv.tt == KTAP_TSHRSTR && (s)->tsv.extra > 0)
+
+#define ktap_numeq(a,b)                ((a)==(b))
+#define ktap_numisnan(L,a)     (!ktap_numeq((a), (a)))
+
+#define ktap_numunm(a)         (-(a))
+
+/*
+ * ** Comparison and arithmetic functions
+ * */
+
+#define KTAP_OPADD       0       /* ORDER TM */
+#define KTAP_OPSUB       1
+#define KTAP_OPMUL       2
+#define KTAP_OPDIV       3
+#define KTAP_OPMOD       4
+#define KTAP_OPPOW       5
+#define KTAP_OPUNM       6
+
+#define KTAP_OPEQ        0
+#define KTAP_OPLT        1
+#define KTAP_OPLE        2
+
+
+/*
+ * WARNING: if you change the order of this enumeration,
+ * grep "ORDER RESERVED"
+ */
+enum RESERVED {
+       /* terminal symbols denoted by reserved words */
+       TK_TRACE = FIRST_RESERVED, TK_TRACE_END,
+       TK_ARGEVENT, TK_ARGNAME,
+       TK_ARG1, TK_ARG2, TK_ARG3, TK_ARG4, TK_ARG5, TK_ARG6, TK_ARG7, TK_ARG8,
+       TK_ARG9, TK_PROFILE, TK_TICK,
+       TK_AND, TK_BREAK,
+       TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
+       TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
+       TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
+       /* other terminal symbols */
+       TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_INCR, TK_DBCOLON,
+       TK_EOS, TK_NUMBER, TK_NAME, TK_STRING
+};
+
+/* number of reserved words */
+#define NUM_RESERVED    ((int)(TK_WHILE-FIRST_RESERVED + 1))
+
+#define EOZ     (0)                    /* end of stream */
+
+typedef union {
+       ktap_number r;
+       ktap_string *ts;
+} ktap_seminfo;  /* semantics information */
+
+
+typedef struct ktap_token {
+       int token;
+       ktap_seminfo seminfo;
+} ktap_token;
+
+typedef struct ktap_mbuffer {
+       char *buffer;
+       size_t n;
+       size_t buffsize;
+} ktap_mbuffer;
+
+#define mbuff_init(buff)       ((buff)->buffer = NULL, (buff)->buffsize = 0)
+#define mbuff(buff)            ((buff)->buffer)
+#define mbuff_reset(buff)      ((buff)->n = 0, memset((buff)->buffer, 0, (buff)->buffsize))
+#define mbuff_len(buff)                ((buff)->n)
+#define mbuff_size(buff)       ((buff)->buffsize)
+
+#define mbuff_resize(buff, size) \
+       (ktapc_realloc((buff)->buffer, (buff)->buffsize, size, char), \
+       (buff)->buffsize = size)
+
+#define mbuff_free(buff)        mbuff_resize(buff, 0)
+
+
+/*
+ * state of the lexer plus state of the parser when shared by all
+ * functions
+ */
+typedef struct ktap_lexstate {
+       char *ptr; /* source file reading position */
+       int current;  /* current character (charint) */
+       int linenumber;  /* input line counter */
+       int lastline;  /* line of last token `consumed' */
+       ktap_token t;  /* current token */
+       ktap_token lookahead;  /* look ahead token */
+       struct ktap_funcstate *fs;  /* current function (parser) */
+       ktap_mbuffer *buff;  /* buffer for tokens */
+       struct ktap_dyndata *dyd;  /* dynamic structures used by the parser */
+       ktap_string *source;  /* current source name */
+       ktap_string *envn;  /* environment variable name */
+       char decpoint;  /* locale decimal point */
+       int nCcalls;
+} ktap_lexstate;
+
+
+/*
+ * Expression descriptor
+ */
+typedef enum {
+       VVOID,        /* no value */
+       VNIL,
+       VTRUE,
+       VFALSE,
+       VK,           /* info = index of constant in `k' */
+       VKNUM,        /* nval = numerical value */
+       VNONRELOC,    /* info = result register */
+       VLOCAL,       /* info = local register */
+       VUPVAL,       /* info = index of upvalue in 'upvalues' */
+       VINDEXED,     /* t = table register/upvalue; idx = index R/K */
+       VJMP,         /* info = instruction pc */
+       VRELOCABLE,   /* info = instruction pc */
+       VCALL,        /* info = instruction pc */
+       VVARARG,      /* info = instruction pc */
+       VEVENT,
+       VEVENTNAME,
+       VEVENTARG,
+} expkind;
+
+
+#define vkisvar(k)      (VLOCAL <= (k) && (k) <= VINDEXED)
+#define vkisinreg(k)    ((k) == VNONRELOC || (k) == VLOCAL)
+
+typedef struct ktap_expdesc {
+       expkind k;
+       union {
+               struct {  /* for indexed variables (VINDEXED) */
+                       short idx;  /* index (R/K) */
+                       u8 t;  /* table (register or upvalue) */
+                       u8 vt;  /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
+               } ind;
+               int info;  /* for generic use */
+               ktap_number nval;  /* for VKNUM */
+       } u;
+       int t;  /* patch list of `exit when true' */
+       int f;  /* patch list of `exit when false' */
+} ktap_expdesc;
+
+
+typedef struct ktap_vardesc {
+       short idx;  /* variable index in stack */
+} ktap_vardesc;
+
+
+/* description of pending goto statements and label statements */
+typedef struct ktap_labeldesc {
+       ktap_string *name;  /* label identifier */
+       int pc;  /* position in code */
+       int line;  /* line where it appeared */
+       u8 nactvar;  /* local level where it appears in current block */
+} ktap_labeldesc;
+
+
+/* list of labels or gotos */
+typedef struct ktap_labellist {
+       ktap_labeldesc *arr;  /* array */
+       int n;  /* number of entries in use */
+       int size;  /* array size */
+} ktap_labellist;
+
+
+/* dynamic structures used by the parser */
+typedef struct ktap_dyndata {
+       struct {  /* list of active local variables */
+               ktap_vardesc *arr;
+               int n;
+               int size;
+       } actvar;
+       ktap_labellist gt;  /* list of pending gotos */
+       ktap_labellist label;   /* list of active labels */
+} ktap_dyndata;
+
+
+/* control of blocks */
+struct ktap_blockcnt;  /* defined in lparser.c */
+
+
+/* state needed to generate code for a given function */
+typedef struct ktap_funcstate {
+       ktap_proto *f;  /* current function header */
+       ktap_table *h;  /* table to find (and reuse) elements in `k' */
+       struct ktap_funcstate *prev;  /* enclosing function */
+       struct ktap_lexstate *ls;  /* lexical state */
+       struct ktap_blockcnt *bl;  /* chain of current blocks */
+       int pc;  /* next position to code (equivalent to `ncode') */
+       int lasttarget;   /* 'label' of last 'jump label' */
+       int jpc;  /* list of pending jumps to `pc' */
+       int nk;  /* number of elements in `k' */
+       int np;  /* number of elements in `p' */
+       int firstlocal;  /* index of first local var (in ktap_dyndata array) */
+       short nlocvars;  /* number of elements in 'f->locvars' */
+       u8 nactvar;  /* number of active local variables */
+       u8 nups;  /* number of upvalues */
+       u8 freereg;  /* first free register */
+} ktap_funcstate;
+
+
+/*
+ * Marks the end of a patch list. It is an invalid value both as an absolute
+ * address, and as a list link (would link an element to itself).
+ */
+#define NO_JUMP (-1)
+
+
+/*
+ * grep "ORDER OPR" if you change these enums  (ORDER OP)
+ */
+typedef enum BinOpr {
+       OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
+       OPR_CONCAT,
+       OPR_EQ, OPR_LT, OPR_LE,
+       OPR_NE, OPR_GT, OPR_GE,
+       OPR_AND, OPR_OR,
+       OPR_NOBINOPR
+} BinOpr;
+
+
+typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
+
+
+#define getcode(fs,e)   ((fs)->f->code[(e)->u.info])
+
+#define codegen_codeAsBx(fs,o,A,sBx)       codegen_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
+
+#define codegen_setmultret(fs,e)   codegen_setreturns(fs, e, KTAP_MULTRET)
+
+#define codegen_jumpto(fs,t)       codegen_patchlist(fs, codegen_jump(fs), t)
+
+
+#define ktapc_realloc(v, osize, nsize, t) \
+        ((v) = (t *)ktapc_reallocv(v, osize * sizeof(t), nsize * sizeof(t)))
+
+#define ktapc_reallocvector(v,oldn,n,t)        ktapc_realloc(v,oldn,n,t)
+
+
+#define ktapc_growvector(v,nelems,size,t,limit,e) \
+          if ((nelems)+1 > (size)) \
+            ((v)=(t *)ktapc_growaux(v,&(size),sizeof(t),limit,e))
+
+
+void lex_init();
+ktap_string *lex_newstring(ktap_lexstate *ls, const char *str, size_t l);
+const char *lex_token2str(ktap_lexstate *ls, int token);
+void lex_syntaxerror(ktap_lexstate *ls, const char *msg);
+void lex_setinput(ktap_lexstate *ls, char *ptr, ktap_string *source, int firstchar);
+void lex_next(ktap_lexstate *ls);
+int lex_lookahead(ktap_lexstate *ls);
+void lex_read_string_until(ktap_lexstate *ls, int c);
+ktap_closure *ktapc_parser(char *pos, const char *name);
+ktap_string *ktapc_ts_new(const char *str);
+int ktapc_ts_eqstr(ktap_string *a, ktap_string *b);
+ktap_string *ktapc_ts_newlstr(const char *str, size_t l);
+ktap_proto *ktapc_newproto();
+ktap_table *ktapc_table_new();
+const ktap_value *ktapc_table_get(ktap_table *t, const ktap_value *key);
+void ktapc_table_setvalue(ktap_table *t, const ktap_value *key, ktap_value *val);
+ktap_closure *ktapc_newlclosure(int n);
+char *ktapc_sprintf(const char *fmt, ...);
+
+void *ktapc_reallocv(void *block, size_t osize, size_t nsize);
+void *ktapc_growaux(void *block, int *size, size_t size_elems, int limit,
+                   const char *what);
+
+void ktapio_exit(void);
+int ktapio_create(const char *output_filename);
+
+ktap_string *ktapc_parse_eventdef(ktap_string *eventdef);
+void cleanup_event_resources(void);
+
+extern int verbose;
+#define verbose_printf(...) \
+       if (verbose)    \
+               printf("[verbose] " __VA_ARGS__);
+
+#define ktapc_equalobj(t1, t2) kp_equalobjv(NULL, t1, t2)
+
+
+#include "../include/ktap_opcodes.h"
+
+int codegen_stringK(ktap_funcstate *fs, ktap_string *s);
+void codegen_indexed(ktap_funcstate *fs, ktap_expdesc *t, ktap_expdesc *k);
+void codegen_setreturns(ktap_funcstate *fs, ktap_expdesc *e, int nresults);
+void codegen_reserveregs(ktap_funcstate *fs, int n);
+void codegen_exp2nextreg(ktap_funcstate *fs, ktap_expdesc *e);
+void codegen_nil(ktap_funcstate *fs, int from, int n);
+void codegen_patchlist(ktap_funcstate *fs, int list, int target);
+void codegen_patchclose(ktap_funcstate *fs, int list, int level);
+int codegen_jump(ktap_funcstate *fs);
+void codegen_patchtohere(ktap_funcstate *fs, int list);
+int codegen_codeABx(ktap_funcstate *fs, OpCode o, int a, unsigned int bc);
+void codegen_ret(ktap_funcstate *fs, int first, int nret);
+void codegen_exp2anyregup(ktap_funcstate *fs, ktap_expdesc *e);
+void codegen_exp2val(ktap_funcstate *fs, ktap_expdesc *e);
+int codegen_exp2RK(ktap_funcstate *fs, ktap_expdesc *e);
+int codegen_codeABC(ktap_funcstate *fs, OpCode o, int a, int b, int c);
+void codegen_setlist(ktap_funcstate *fs, int base, int nelems, int tostore);
+void codegen_fixline (ktap_funcstate *fs, int line);
+void codegen_dischargevars(ktap_funcstate *fs, ktap_expdesc *e);
+void codegen_self(ktap_funcstate *fs, ktap_expdesc *e, ktap_expdesc *key);
+void codegen_prefix(ktap_funcstate *fs, UnOpr op, ktap_expdesc *e, int line);
+void codegen_infix(ktap_funcstate *fs, BinOpr op, ktap_expdesc *v);
+void codegen_posfix(ktap_funcstate *fs, BinOpr op, ktap_expdesc *e1, ktap_expdesc *e2, int line);
+void codegen_setoneret(ktap_funcstate *fs, ktap_expdesc *e);
+void codegen_storevar(ktap_funcstate *fs, ktap_expdesc *var, ktap_expdesc *ex);
+void codegen_storeincr(ktap_funcstate *fs, ktap_expdesc *var, ktap_expdesc *ex);
+void codegen_goiftrue(ktap_funcstate *fs, ktap_expdesc *e);
+int codegen_getlabel(ktap_funcstate *fs);
+int codegen_codek(ktap_funcstate *fs, int reg, int k);
+int codegen_numberK(ktap_funcstate *fs, ktap_number r);
+void codegen_checkstack(ktap_funcstate *fs, int n);
+void codegen_goiffalse(ktap_funcstate *fs, ktap_expdesc *e);
+void codegen_concat(ktap_funcstate *fs, int *l1, int l2);
+int codegen_exp2anyreg(ktap_funcstate *fs, ktap_expdesc *e);
+
+typedef int (*ktap_writer)(const void* p, size_t sz, void* ud);
+int ktapc_dump(const ktap_proto *f, ktap_writer w, void *data, int strip);
+
+void ktapc_chunkid(char *out, const char *source, size_t bufflen);
+int ktapc_str2d(const char *s, size_t len, ktap_number *result);
+int ktapc_hexavalue(int c);
+ktap_number ktapc_arith(int op, ktap_number v1, ktap_number v2);
+int ktapc_int2fb(unsigned int x);
+
+bool strglobmatch(const char *str, const char *pat);
+
diff --git a/drivers/staging/ktap/userspace/ktapio.c b/drivers/staging/ktap/userspace/ktapio.c
new file mode 100644 (file)
index 0000000..f9bcab4
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * ktapio.c - ring buffer transport in userspace
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <sys/signal.h>
+#include <fcntl.h>
+#include <pthread.h>
+
+#define MAX_BUFLEN  131072
+#define PATH_MAX 128
+
+#define handle_error(str) do { perror(str); exit(-1); } while(0)
+
+extern pid_t ktap_pid;
+
+void sigfunc(int signo)
+{
+       /* should not not reach here */
+}
+
+static void block_sigint()
+{
+       sigset_t mask;
+
+       sigemptyset(&mask);
+       sigaddset(&mask, SIGINT);
+
+       pthread_sigmask(SIG_BLOCK, &mask, NULL);
+}
+
+static void *reader_thread(void *data)
+{
+       char buf[MAX_BUFLEN];
+       char filename[PATH_MAX];
+       const char *output = data; 
+       int failed = 0, fd, out_fd, len;
+
+       block_sigint();
+
+       if (output) {
+               out_fd = open(output, O_CREAT | O_WRONLY | O_TRUNC,
+                                       S_IRUSR|S_IWUSR);
+               if (out_fd < 0) {
+                       fprintf(stderr, "Cannot open output file %s\n", output);
+                       return NULL;
+               }
+       } else
+               out_fd = 2;
+
+       sprintf(filename, "/sys/kernel/debug/ktap/trace_pipe_%d", ktap_pid);
+
+ open_again:
+       fd = open(filename, O_RDONLY);
+       if (fd < 0) {
+               usleep(10000);
+
+               if (failed++ == 10) {
+                       fprintf(stderr, "Cannot open file %s\n", filename);
+                       return NULL;
+               }
+               goto open_again;
+       }
+
+       while ((len = read(fd, buf, sizeof(buf))) > 0)
+               write(out_fd, buf, len);
+
+       close(fd);
+       close(out_fd);
+
+       return NULL;
+}
+
+int ktapio_create(const char *output)
+{
+       pthread_t reader;
+
+       signal(SIGINT, sigfunc);
+
+       if (pthread_create(&reader, NULL, reader_thread, (void *)output) < 0)
+               handle_error("pthread_create reader_thread failed\n");
+
+       return 0;
+}
+
diff --git a/drivers/staging/ktap/userspace/lex.c b/drivers/staging/ktap/userspace/lex.c
new file mode 100644 (file)
index 0000000..484dd7f
--- /dev/null
@@ -0,0 +1,622 @@
+/*
+ * lex.c - ktap lexical analyzer
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include "../include/ktap_types.h"
+#include "ktapc.h"
+
+#define next(ls) (ls->current = *ls->ptr++)
+
+#define currIsNewline(ls)      (ls->current == '\n' || ls->current == '\r')
+
+#define KTAP_MINBUFFER   32
+
+/* ORDER RESERVED */
+static const char *const ktap_tokens [] = {
+       "trace", "trace_end", "argevent", "argname",
+       "arg1", "arg2", "arg3", "arg4", "arg5", "arg6", "arg7", "arg9", "arg9",
+       "profile", "tick",
+       "and", "break", "do", "else", "elseif",
+       "end", "false", "for", "function", "goto", "if",
+       "in", "local", "nil", "not", "or", "repeat",
+       "return", "then", "true", "until", "while",
+       "..", "...", "==", ">=", "<=", "!=", "+=", "::", "<eof>",
+       "<number>", "<name>", "<string>"
+};
+
+#define save_and_next(ls) (save(ls, ls->current), next(ls))
+
+static void lexerror(ktap_lexstate *ls, const char *msg, int token);
+
+static void save(ktap_lexstate *ls, int c)
+{
+       ktap_mbuffer *b = ls->buff;
+       if (mbuff_len(b) + 1 > mbuff_size(b)) {
+               size_t newsize;
+               if (mbuff_size(b) >= MAX_SIZET / 2)
+                       lexerror(ls, "lexical element too long", 0);
+               newsize = mbuff_size(b) * 2;
+               mbuff_resize(b, newsize);
+       }
+       b->buffer[mbuff_len(b)++] = (char)c;
+}
+
+void lex_init()
+{
+       int i;
+       for (i = 0; i < NUM_RESERVED; i++) {
+               ktap_string *ts = ktapc_ts_new(ktap_tokens[i]);
+               ts->tsv.extra = (u8)(i+1);  /* reserved word */
+       }
+}
+
+const char *lex_token2str(ktap_lexstate *ls, int token)
+{
+       if (token < FIRST_RESERVED) {
+               ktap_assert(token == (unsigned char)token);
+               return (isprint(token)) ? ktapc_sprintf(KTAP_QL("%c"), token) :
+                       ktapc_sprintf("char(%d)", token);
+       } else {
+               const char *s = ktap_tokens[token - FIRST_RESERVED];
+               if (token < TK_EOS)
+                       return ktapc_sprintf(KTAP_QS, s);
+               else
+                       return s;
+       }
+}
+
+static const char *txtToken(ktap_lexstate *ls, int token)
+{
+       switch (token) {
+       case TK_NAME:
+       case TK_STRING:
+       case TK_NUMBER:
+               save(ls, '\0');
+               return ktapc_sprintf(KTAP_QS, mbuff(ls->buff));
+       default:
+               return lex_token2str(ls, token);
+       }
+}
+
+static void lexerror(ktap_lexstate *ls, const char *msg, int token)
+{
+       char buff[KTAP_IDSIZE];
+       char *newmsg;
+
+       ktapc_chunkid(buff, getstr(ls->source), KTAP_IDSIZE);
+       newmsg = ktapc_sprintf("%s:%d: %s", buff, ls->linenumber, msg);
+       if (token)
+               newmsg = ktapc_sprintf("%s near %s", newmsg, txtToken(ls, token));
+       printf("lexerror: %s\n", newmsg);
+       exit(EXIT_FAILURE);
+}
+
+void lex_syntaxerror(ktap_lexstate *ls, const char *msg)
+{
+       lexerror(ls, msg, ls->t.token);
+}
+
+/*
+ * creates a new string and anchors it in function's table so that
+ * it will not be collected until the end of the function's compilation
+ * (by that time it should be anchored in function's prototype)
+ */
+ktap_string *lex_newstring(ktap_lexstate *ls, const char *str, size_t l)
+{
+       const ktap_value *o;  /* entry for `str' */
+       ktap_value val;  /* entry for `str' */
+       ktap_value tsv;
+       ktap_string *ts = ktapc_ts_newlstr(str, l);  /* create new string */
+       setsvalue(&tsv, ts); 
+       o = ktapc_table_get(ls->fs->h, &tsv);
+       if (ttisnil(o)) {  /* not in use yet? (see 'addK') */
+               /* boolean value does not need GC barrier;
+               table has no metatable, so it does not need to invalidate cache */
+               setbvalue(&val, 1);  /* t[string] = true */
+               ktapc_table_setvalue(ls->fs->h, &tsv, &val);
+       }
+       return ts;
+}
+
+/*
+ * increment line number and skips newline sequence (any of
+ * \n, \r, \n\r, or \r\n)
+ */
+static void inclinenumber(ktap_lexstate *ls)
+{
+       int old = ls->current;
+       ktap_assert(currIsNewline(ls));
+       next(ls);  /* skip `\n' or `\r' */
+       if (currIsNewline(ls) && ls->current != old)
+               next(ls);  /* skip `\n\r' or `\r\n' */
+       if (++ls->linenumber >= MAX_INT)
+               lex_syntaxerror(ls, "chunk has too many lines");
+}
+
+void lex_setinput(ktap_lexstate *ls, char *ptr, ktap_string *source, int firstchar)
+{
+       ls->decpoint = '.';
+       ls->current = firstchar;
+       ls->lookahead.token = TK_EOS;  /* no look-ahead token */
+       ls->ptr = ptr;
+       ls->fs = NULL;
+       ls->linenumber = 1;
+       ls->lastline = 1;
+       ls->source = source;
+       ls->envn = ktapc_ts_new(KTAP_ENV);  /* create env name */
+       mbuff_resize(ls->buff, KTAP_MINBUFFER);  /* initialize buffer */
+}
+
+/*
+ * =======================================================
+ * LEXICAL ANALYZER
+ * =======================================================
+ */
+static int check_next(ktap_lexstate *ls, const char *set)
+{
+       if (ls->current == '\0' || !strchr(set, ls->current))
+               return 0;
+       save_and_next(ls);
+       return 1;
+}
+
+/*
+ * change all characters 'from' in buffer to 'to'
+ */
+static void buffreplace(ktap_lexstate *ls, char from, char to)
+{
+       size_t n = mbuff_len(ls->buff);
+       char *p = mbuff(ls->buff);
+       while (n--)
+               if (p[n] == from) p[n] = to;
+}
+
+#if !defined(getlocaledecpoint)
+#define getlocaledecpoint()    (localeconv()->decimal_point[0])
+#endif
+
+#define mbuff2d(b,e)   ktapc_str2d(mbuff(b), mbuff_len(b) - 1, e)
+
+/*
+ * in case of format error, try to change decimal point separator to
+ * the one defined in the current locale and check again
+ */
+static void trydecpoint(ktap_lexstate *ls, ktap_seminfo *seminfo)
+{
+       char old = ls->decpoint;
+       ls->decpoint = getlocaledecpoint();
+       buffreplace(ls, old, ls->decpoint);  /* try new decimal separator */
+       if (!mbuff2d(ls->buff, &seminfo->r)) {
+               /* format error with correct decimal point: no more options */
+               buffreplace(ls, ls->decpoint, '.');  /* undo change (for error message) */
+               lexerror(ls, "malformed number", TK_NUMBER);
+       }
+}
+
+/*
+ * this function is quite liberal in what it accepts, as 'ktapc_str2d'
+ * will reject ill-formed numerals.
+ */
+static void read_numeral(ktap_lexstate *ls, ktap_seminfo *seminfo)
+{
+       const char *expo = "Ee";
+       int first = ls->current;
+
+       ktap_assert(isdigit(ls->current));
+       save_and_next(ls);
+       if (first == '0' && check_next(ls, "Xx"))  /* hexadecimal? */
+               expo = "Pp";
+       for (;;) {
+               if (check_next(ls, expo))  /* exponent part? */
+                       check_next(ls, "+-");  /* optional exponent sign */
+               if (isxdigit(ls->current) || ls->current == '.')
+                       save_and_next(ls);
+               else
+                       break;
+       }
+       save(ls, '\0');
+       buffreplace(ls, '.', ls->decpoint);  /* follow locale for decimal point */
+       if (!mbuff2d(ls->buff, &seminfo->r))  /* format error? */
+               trydecpoint(ls, seminfo); /* try to update decimal point separator */
+}
+
+/*
+ * skip a sequence '[=*[' or ']=*]' and return its number of '='s or
+ * -1 if sequence is malformed
+ */
+static int skip_sep(ktap_lexstate *ls)
+{
+       int count = 0;
+       int s = ls->current;
+
+       ktap_assert(s == '[' || s == ']');
+       save_and_next(ls);
+       while (ls->current == '=') {
+               save_and_next(ls);
+               count++;
+       }
+       return (ls->current == s) ? count : (-count) - 1;
+}
+
+static void read_long_string(ktap_lexstate *ls, ktap_seminfo *seminfo, int sep)
+{
+       save_and_next(ls);  /* skip 2nd `[' */
+       if (currIsNewline(ls))  /* string starts with a newline? */
+               inclinenumber(ls);  /* skip it */
+       for (;;) {
+               switch (ls->current) {
+               case EOZ:
+                       lexerror(ls, (seminfo) ? "unfinished long string" :
+                               "unfinished long comment", TK_EOS);
+                       break;  /* to avoid warnings */
+               case ']': {
+                       if (skip_sep(ls) == sep) {
+                               save_and_next(ls);  /* skip 2nd `]' */
+                               goto endloop;
+                       }
+                       break;
+               }
+               case '\n':
+               case '\r': {
+                       save(ls, '\n');
+                       inclinenumber(ls);
+                       /* avoid wasting space */
+                       if (!seminfo)
+                               mbuff_reset(ls->buff);
+                       break;
+               }
+               default: {
+                       if (seminfo)
+                               save_and_next(ls);
+                       else
+                               next(ls);
+               }
+               }
+       }
+
+ endloop:
+       if (seminfo)
+               seminfo->ts = lex_newstring(ls, mbuff(ls->buff) + (2 + sep),
+                       mbuff_len(ls->buff) - 2*(2 + sep));
+}
+
+static void escerror(ktap_lexstate *ls, int *c, int n, const char *msg)
+{
+       int i;
+       mbuff_reset(ls->buff);  /* prepare error message */
+       save(ls, '\\');
+       for (i = 0; i < n && c[i] != EOZ; i++)
+               save(ls, c[i]);
+       lexerror(ls, msg, TK_STRING);
+}
+
+static int readhexaesc(ktap_lexstate *ls)
+{
+       int c[3], i;  /* keep input for error message */
+       int r = 0;  /* result accumulator */
+       c[0] = 'x';  /* for error message */
+       for (i = 1; i < 3; i++) {  /* read two hexa digits */
+               c[i] = next(ls);
+               if (!isxdigit(c[i]))
+                       escerror(ls, c, i + 1, "hexadecimal digit expected");
+               r = (r << 4) + ktapc_hexavalue(c[i]);
+       }
+       return r;
+}
+
+static int readdecesc(ktap_lexstate *ls)
+{
+       int c[3], i;
+       int r = 0;  /* result accumulator */
+       for (i = 0; i < 3 && isdigit(ls->current); i++) {  /* read up to 3 digits */
+               c[i] = ls->current;
+               r = 10*r + c[i] - '0';
+               next(ls);
+       }
+       if (r > UCHAR_MAX)
+               escerror(ls, c, i, "decimal escape too large");
+       return r;
+}
+
+static void read_string(ktap_lexstate *ls, int del, ktap_seminfo *seminfo)
+{
+       save_and_next(ls);  /* keep delimiter (for error messages) */
+       while (ls->current != del) {
+               switch (ls->current) {
+               case EOZ:
+                       lexerror(ls, "unfinished string", TK_EOS);
+                       break;  /* to avoid warnings */
+               case '\n':
+               case '\r':
+                       lexerror(ls, "unfinished string", TK_STRING);
+                       break;  /* to avoid warnings */
+               case '\\': {  /* escape sequences */
+                       int c;  /* final character to be saved */
+                       next(ls);  /* do not save the `\' */
+                       switch (ls->current) {
+                       case 'a': c = '\a'; goto read_save;
+                       case 'b': c = '\b'; goto read_save;
+                       case 'f': c = '\f'; goto read_save;
+                       case 'n': c = '\n'; goto read_save;
+                       case 'r': c = '\r'; goto read_save;
+                       case 't': c = '\t'; goto read_save;
+                       case 'v': c = '\v'; goto read_save;
+                       case 'x': c = readhexaesc(ls); goto read_save;
+                       case '\n': case '\r':
+                               inclinenumber(ls); c = '\n'; goto only_save;
+                       case '\\': case '\"': case '\'':
+                               c = ls->current; goto read_save;
+                       case EOZ: goto no_save;  /* will raise an error next loop */
+                       case 'z': {  /* zap following span of spaces */
+                               next(ls);  /* skip the 'z' */
+                               while (isspace(ls->current)) {
+                                       if (currIsNewline(ls))
+                                               inclinenumber(ls);
+                                       else
+                                               next(ls);
+                               }
+                               goto no_save;
+                       }
+                       default: {
+                               if (!isdigit(ls->current))
+                                       escerror(ls, &ls->current, 1, "invalid escape sequence");
+                               /* digital escape \ddd */
+                               c = readdecesc(ls);
+                               goto only_save;
+                       }
+                       }
+ read_save:
+                       next(ls);  /* read next character */
+ only_save:
+                       save(ls, c);  /* save 'c' */
+ no_save:
+                       break;
+               }
+               default:
+                       save_and_next(ls);
+               }
+       }
+       save_and_next(ls);  /* skip delimiter */
+       seminfo->ts = lex_newstring(ls, mbuff(ls->buff) + 1, mbuff_len(ls->buff) - 2);
+}
+
+static int llex(ktap_lexstate *ls, ktap_seminfo *seminfo)
+{
+       mbuff_reset(ls->buff);
+
+       for (;;) {
+               switch (ls->current) {
+               case '\n': case '\r': {  /* line breaks */
+                       inclinenumber(ls);
+                       break;
+               }
+               case ' ': case '\f': case '\t': case '\v': {  /* spaces */
+                       next(ls);
+                       break;
+               }
+               case '#': {
+                       while (!currIsNewline(ls) && ls->current != EOZ)
+                               next(ls);  /* skip until end of line (or end of file) */
+                       break;
+               }
+               #if 0
+               case '-': {  /* '-' or '--' (comment) */
+                       next(ls);
+                       if (ls->current != '-')
+                               return '-';
+                       /* else is a comment */
+                       next(ls);
+                       if (ls->current == '[') {  /* long comment? */
+                               int sep = skip_sep(ls);
+                               mbuff_reset(ls->buff);  /* `skip_sep' may dirty the buffer */
+                               if (sep >= 0) {
+                                       read_long_string(ls, NULL, sep);  /* skip long comment */
+                                       mbuff_reset(ls->buff);  /* previous call may dirty the buff. */
+                                       break;
+                               }
+                       }
+                       /* else short comment */
+                       while (!currIsNewline(ls) && ls->current != EOZ)
+                               next(ls);  /* skip until end of line (or end of file) */
+                       break;
+               }
+               #endif
+               case '[': {  /* long string or simply '[' */
+                       int sep = skip_sep(ls);
+                       if (sep >= 0) {
+                               read_long_string(ls, seminfo, sep);
+                               return TK_STRING;
+                       }
+                       else if (sep == -1)
+                               return '[';
+                       else
+                               lexerror(ls, "invalid long string delimiter", TK_STRING);
+               }
+               case '+': {
+                       next(ls);
+                       if (ls->current != '=')
+                               return '+';
+                       else {
+                               next(ls);
+                               return TK_INCR;
+                       }
+               }
+               case '=': {
+                       next(ls);
+                       if (ls->current != '=')
+                               return '=';
+                       else {
+                               next(ls);
+                               return TK_EQ;
+                       }
+               }
+               case '<': {
+                       next(ls);
+                       if (ls->current != '=')
+                               return '<';
+                       else {
+                               next(ls);
+                               return TK_LE;
+                       }
+               }
+               case '>': {
+                       next(ls);
+                       if (ls->current != '=')
+                               return '>';
+                       else {
+                               next(ls);
+                               return TK_GE;
+                       }
+               }
+               case '!': {
+                       next(ls);
+                       if (ls->current != '=')
+                               return TK_NOT;
+                       else {
+                               next(ls);
+                               return TK_NE;
+                       }
+               }
+               case ':': {
+                       next(ls);
+                       if (ls->current != ':')
+                               return ':';
+                       else {
+                               next(ls);
+                               return TK_DBCOLON;
+                       }
+               }
+               case '"': case '\'': {  /* short literal strings */
+                       read_string(ls, ls->current, seminfo);
+                       return TK_STRING;
+               }
+               case '.': {  /* '.', '..', '...', or number */
+                       save_and_next(ls);
+                       if (check_next(ls, ".")) {
+                               if (check_next(ls, "."))
+                                       return TK_DOTS;   /* '...' */
+                               else
+                                       return TK_CONCAT;   /* '..' */
+                       }
+                       else if (!isdigit(ls->current))
+                               return '.';
+                       /* else go through */
+               }
+               case '0': case '1': case '2': case '3': case '4':
+               case '5': case '6': case '7': case '8': case '9': {
+                       read_numeral(ls, seminfo);
+                       return TK_NUMBER;
+               }
+               case EOZ: {
+                       return TK_EOS;
+               }
+               case '&': {
+                       next(ls);
+                       if (ls->current != '&')
+                               return '&';
+                       else {
+                               next(ls);
+                               return TK_AND;
+                       }
+               } 
+               case '|': {
+                       next(ls);
+                       if (ls->current != '|')
+                               return '|';
+                       else {
+                               next(ls);
+                               return TK_OR;
+                       }
+               } 
+               default: {
+                       if (islalpha(ls->current)) {
+                               /* identifier or reserved word? */
+                               ktap_string *ts;
+                               do {
+                                       save_and_next(ls);
+                               } while (islalnum(ls->current));
+                               ts = lex_newstring(ls, mbuff(ls->buff),
+                                                       mbuff_len(ls->buff));
+                               seminfo->ts = ts;
+                               if (isreserved(ts))  /* reserved word? */
+                                       return ts->tsv.extra - 1 +
+                                               FIRST_RESERVED;
+                               else {
+                                       return TK_NAME;
+                               }
+                       } else {  /* single-char tokens (+ - / ...) */
+                               int c = ls->current;
+                               next(ls);
+                               return c;
+                       }
+               }
+               }
+       }
+}
+
+void lex_read_string_until(ktap_lexstate *ls, int c)
+{
+       ktap_string *ts;
+       char errmsg[32];
+
+       mbuff_reset(ls->buff);
+
+       while (ls->current == ' ')
+               next(ls);
+
+       do {
+               save_and_next(ls);
+       } while (ls->current != c && ls->current != EOZ);
+
+       if (ls->current != c) {
+               sprintf(errmsg, "expect %c", c);
+               lexerror(ls, errmsg, 0);
+       }
+
+       ts = lex_newstring(ls, mbuff(ls->buff), mbuff_len(ls->buff));
+       ls->t.seminfo.ts = ts;
+       ls->t.token = TK_STRING;
+}
+
+void lex_next(ktap_lexstate *ls)
+{
+       ls->lastline = ls->linenumber;
+       if (ls->lookahead.token != TK_EOS) {  /* is there a look-ahead token? */
+               ls->t = ls->lookahead;  /* use this one */
+               ls->lookahead.token = TK_EOS;  /* and discharge it */
+       } else
+               ls->t.token = llex(ls, &ls->t.seminfo);  /* read next token */
+}
+
+int lex_lookahead(ktap_lexstate *ls)
+{
+       ktap_assert(ls->lookahead.token == TK_EOS);
+       ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
+       return ls->lookahead.token;
+}
+
diff --git a/drivers/staging/ktap/userspace/main.c b/drivers/staging/ktap/userspace/main.c
new file mode 100644 (file)
index 0000000..2aa686a
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ * main.c - ktap compiler and loader entry
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <string.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <math.h>
+
+#include "../include/ktap_types.h"
+#include "../include/ktap_opcodes.h"
+#include "ktapc.h"
+
+
+/*******************************************************************/
+
+void *ktapc_reallocv(void *block, size_t osize, size_t nsize)
+{
+       return kp_reallocv(NULL, block, osize, nsize);
+}
+
+ktap_closure *ktapc_newlclosure(int n)
+{
+       return kp_newlclosure(NULL, n);
+}
+
+ktap_proto *ktapc_newproto()
+{
+       return kp_newproto(NULL);
+}
+
+const ktap_value *ktapc_table_get(ktap_table *t, const ktap_value *key)
+{
+       return kp_table_get(t, key);
+}
+
+void ktapc_table_setvalue(ktap_table *t, const ktap_value *key, ktap_value *val)
+{
+       kp_table_setvalue(NULL, t, key, val);
+}
+
+ktap_table *ktapc_table_new()
+{
+       return kp_table_new(NULL);
+}
+
+ktap_string *ktapc_ts_newlstr(const char *str, size_t l)
+{
+       return kp_tstring_newlstr(NULL, str, l);
+}
+
+ktap_string *ktapc_ts_new(const char *str)
+{
+       return kp_tstring_new(NULL, str);
+}
+
+int ktapc_ts_eqstr(ktap_string *a, ktap_string *b)
+{
+       return kp_tstring_eqstr(a, b);
+}
+
+static void ktapc_runerror(const char *err_msg_fmt, ...)
+{
+       va_list ap;
+
+       fprintf(stderr, "ktapc_runerror\n");
+
+       va_start(ap, err_msg_fmt);
+       vfprintf(stderr, err_msg_fmt, ap);
+       va_end(ap);
+
+       exit(EXIT_FAILURE);
+}
+
+/*
+ * todo: memory leak here
+ */
+char *ktapc_sprintf(const char *fmt, ...)
+{
+       char *msg = malloc(128);
+
+       va_list argp;
+       va_start(argp, fmt);
+       vsprintf(msg, fmt, argp);
+       va_end(argp);
+       return msg;
+}
+
+
+#define MINSIZEARRAY   4
+
+void *ktapc_growaux(void *block, int *size, size_t size_elems, int limit,
+                   const char *what)
+{
+       void *newblock;
+       int newsize;
+
+       if (*size >= limit/2) {  /* cannot double it? */
+               if (*size >= limit)  /* cannot grow even a little? */
+                       ktapc_runerror("too many %s (limit is %d)\n",
+                                       what, limit);
+               newsize = limit;  /* still have at least one free place */
+       } else {
+               newsize = (*size) * 2;
+               if (newsize < MINSIZEARRAY)
+                       newsize = MINSIZEARRAY;  /* minimum size */
+       }
+
+       newblock = ktapc_reallocv(block, (*size) * size_elems, newsize * size_elems);
+       *size = newsize;  /* update only when everything else is OK */
+       return newblock;
+}
+
+/*************************************************************************/
+
+#define print_base(i) \
+       do {    \
+               if (i < f->sizelocvars) /* it's a localvars */ \
+                       printf("%s", getstr(f->locvars[i].varname));  \
+               else \
+                       printf("base + %d", i); \
+       } while (0)
+
+#define print_RKC(instr)       \
+       do {    \
+               if (ISK(GETARG_C(instr))) \
+                       kp_showobj(NULL, k + INDEXK(GETARG_C(instr))); \
+               else \
+                       print_base(GETARG_C(instr)); \
+       } while (0)
+
+static void decode_instruction(ktap_proto *f, int instr)
+{
+       int opcode = GET_OPCODE(instr);
+       ktap_value *k;
+
+       k = f->k;
+
+       printf("%.8x\t", instr);
+       printf("%s\t", ktap_opnames[opcode]);
+
+       switch (opcode) {
+       case OP_GETTABUP:
+               print_base(GETARG_A(instr));
+               printf(" <- ");
+
+               if (GETARG_B(instr) == 0)
+                       printf("global");
+               else
+                       printf("upvalues[%d]", GETARG_B(instr));
+
+               printf("{"); print_RKC(instr); printf("}");
+
+               break;
+       case OP_GETTABLE:
+               print_base(GETARG_A(instr));
+               printf(" <- ");
+
+               print_base(GETARG_B(instr));
+
+               printf("{");
+               print_RKC(instr);
+               printf("}");
+               break;
+       case OP_LOADK:
+               printf("\t");
+               print_base(GETARG_A(instr));
+               printf(" <- ");
+
+               kp_showobj(NULL, k + GETARG_Bx(instr));
+               break;
+       case OP_CALL:
+               printf("\t");
+               print_base(GETARG_A(instr));
+               break;
+       case OP_JMP:
+               printf("\t%d", GETARG_sBx(instr));
+               break;
+       default:
+               break;
+       }
+
+       printf("\n");
+}
+
+static int function_nr = 0;
+
+/* this is a debug function used for check bytecode chunk file */
+static void dump_function(int level, ktap_proto *f)
+{
+       int i;
+
+       printf("\n----------------------------------------------------\n");
+       printf("function %d [level %d]:\n", function_nr++, level);
+       printf("linedefined: %d\n", f->linedefined);
+       printf("lastlinedefined: %d\n", f->lastlinedefined);
+       printf("numparams: %d\n", f->numparams);
+       printf("is_vararg: %d\n", f->is_vararg);
+       printf("maxstacksize: %d\n", f->maxstacksize);
+       printf("source: %s\n", getstr(f->source));
+       printf("sizelineinfo: %d \t", f->sizelineinfo);
+       for (i = 0; i < f->sizelineinfo; i++)
+               printf("%d ", f->lineinfo[i]);
+       printf("\n");
+
+       printf("sizek: %d\n", f->sizek);
+       for (i = 0; i < f->sizek; i++) {
+               switch(f->k[i].type) {
+               case KTAP_TNIL:
+                       printf("\tNIL\n");
+                       break;
+               case KTAP_TBOOLEAN:
+                       printf("\tBOOLEAN: ");
+                       printf("%d\n", f->k[i].val.b);
+                       break;
+               case KTAP_TNUMBER:
+                       printf("\tTNUMBER: ");
+                       printf("%ld\n", f->k[i].val.n);
+                       break;
+               case KTAP_TSTRING:
+                       printf("\tTSTRING: ");
+                       printf("%s\n", svalue(&(f->k[i])));
+
+                       break;
+               default:
+                       printf("\terror: unknow constant type\n");
+               }
+       }
+
+       printf("sizelocvars: %d\n", f->sizelocvars);
+       for (i = 0; i < f->sizelocvars; i++) {
+               printf("\tlocvars: %s startpc: %d endpc: %d\n",
+                       getstr(f->locvars[i].varname), f->locvars[i].startpc,
+                       f->locvars[i].endpc);
+       }
+
+       printf("sizeupvalues: %d\n", f->sizeupvalues);
+       for (i = 0; i < f->sizeupvalues; i++) {
+               printf("\tname: %s instack: %d idx: %d\n",
+                       getstr(f->upvalues[i].name), f->upvalues[i].instack,
+                       f->upvalues[i].idx);
+       }
+
+       printf("\n");
+       printf("sizecode: %d\n", f->sizecode);
+       for (i = 0; i < f->sizecode; i++)
+               decode_instruction(f, f->code[i]);
+
+       printf("sizep: %d\n", f->sizep);
+       for (i = 0; i < f->sizep; i++)
+               dump_function(level + 1, f->p[i]);
+
+}
+
+static void usage(const char *msg_fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, msg_fmt);
+       fprintf(stderr, msg_fmt, ap);
+       va_end(ap);
+
+       fprintf(stderr,
+"Usage: ktap [options] file [script args] -- cmd [args]\n"
+"   or: ktap [options] -e one-liner  -- cmd [args]\n"
+"\n"
+"Options and arguments:\n"
+"  -o file        : send script output to file, instead of stderr\n"
+"  -p pid         : specific tracing pid\n"
+"  -C cpu         : cpu to monitor in system-wide\n"
+"  -T             : show timestamp for event\n"
+"  -V             : show version\n"
+"  -v             : enable verbose mode\n"
+"  -s             : simple event tracing\n"
+"  -b             : list byte codes\n"
+"  file           : program read from script file\n"
+"  -- cmd [args]  : workload to tracing\n");
+
+       exit(EXIT_FAILURE);
+}
+
+ktap_global_state dummy_global_state;
+
+static void init_dummy_global_state()
+{
+       memset(&dummy_global_state, 0, sizeof(ktap_global_state));
+       dummy_global_state.seed = 201236;
+
+        kp_tstring_resize(NULL, 32); /* set inital string hashtable size */
+}
+
+#define handle_error(str) do { perror(str); exit(-1); } while(0)
+
+static struct ktap_parm uparm;
+static int ktap_trunk_mem_size = 1024;
+
+static int ktapc_writer(const void* p, size_t sz, void* ud)
+{
+       if (uparm.trunk_len + sz > ktap_trunk_mem_size) {
+               int new_size = (uparm.trunk_len + sz) * 2;
+               uparm.trunk = realloc(uparm.trunk, new_size);
+               ktap_trunk_mem_size = new_size;
+       }
+
+       memcpy(uparm.trunk + uparm.trunk_len, p, sz);
+       uparm.trunk_len += sz;
+
+       return 0;
+}
+
+
+static int forks;
+static char **workload_argv;
+
+static int fork_workload(int ktap_fd)
+{
+       int pid;
+
+       pid = fork();
+       if (pid < 0)
+               handle_error("failed to fork");
+
+       if (pid > 0)
+               return pid;
+
+       signal(SIGTERM, SIG_DFL);
+
+       execvp("", workload_argv);
+
+       /*
+        * waiting ktapvm prepare all tracing event
+        * make it more robust in future.
+        */
+       pause();
+
+       execvp(workload_argv[0], workload_argv);
+
+       perror(workload_argv[0]);
+       exit(-1);
+
+       return -1;
+}
+
+#define KTAPVM_PATH "/sys/kernel/debug/ktap/ktapvm"
+
+static char *output_filename;
+pid_t ktap_pid;
+
+static int run_ktapvm()
+{
+        int ktapvm_fd, ktap_fd;
+       int ret;
+
+       ktap_pid = getpid();
+
+       ktapvm_fd = open(KTAPVM_PATH, O_RDONLY);
+       if (ktapvm_fd < 0)
+               handle_error("open " KTAPVM_PATH " failed");
+
+       ktap_fd = ioctl(ktapvm_fd, 0, NULL);
+       if (ktap_fd < 0)
+               handle_error("ioctl ktapvm failed");
+
+       ktapio_create(output_filename);
+
+       if (forks) {
+               uparm.trace_pid = fork_workload(ktap_fd);
+               uparm.workload = 1;
+       }
+
+       ret = ioctl(ktap_fd, KTAP_CMD_IOC_RUN, &uparm);
+
+       close(ktap_fd);
+       close(ktapvm_fd);
+
+       return ret;
+}
+
+int verbose;
+static int dump_bytecode;
+static char oneline_src[1024];
+static int trace_pid = -1;
+static int trace_cpu = -1;
+static int print_timestamp;
+
+#define SIMPLE_ONE_LINER_FMT   \
+       "trace %s { print(cpu(), tid(), execname(), argevent) }"
+
+static const char *script_file;
+static int script_args_start;
+static int script_args_end;
+
+static void parse_option(int argc, char **argv)
+{
+       char pid[32] = {0};
+       char cpu_str[32] = {0};
+       char *next_arg;
+       int i, j;
+
+       for (i = 1; i < argc; i++) {
+               if (argv[i][0] != '-') {
+                       script_file = argv[i];
+                       if (!script_file)
+                               usage("");
+
+                       script_args_start = i + 1;
+                       script_args_end = argc;
+
+                       for (j = i + 1; j < argc; j++) {
+                               if (argv[j][0] == '-' && argv[j][1] == '-')
+                                       goto found_cmd;
+                       }
+
+                       return;
+               }
+
+               if (argv[i][0] == '-' && argv[i][1] == '-') {
+                       j = i;
+                       goto found_cmd;
+               }
+
+               next_arg = argv[i + 1];
+
+               switch (argv[i][1]) {
+               case 'o':
+                       output_filename = malloc(strlen(next_arg) + 1);
+                       if (!output_filename)
+                               return;
+
+                       strncpy(output_filename, next_arg, strlen(next_arg));
+                       i++;
+                       break;
+               case 'e':
+                       strncpy(oneline_src, next_arg, strlen(next_arg));
+                       i++;
+                       break;
+               case 'p':
+                       strncpy(pid, next_arg, strlen(next_arg));
+                       trace_pid = atoi(pid);
+                       i++;
+                       break;
+               case 'C':
+                       strncpy(cpu_str, next_arg, strlen(next_arg));
+                       trace_cpu = atoi(cpu_str);
+                       i++;
+                       break;
+               case 'T':
+                       print_timestamp = 1;
+                       break;
+               case 'v':
+                       verbose = 1;
+                       break;
+               case 's':
+                       sprintf(oneline_src, SIMPLE_ONE_LINER_FMT, next_arg);
+                       i++;
+                       break;
+               case 'b':
+                       dump_bytecode = 1;
+                       break;
+               case 'V':
+               case '?':
+               case 'h':
+                       usage("");
+                       break;
+               default:
+                       usage("wrong argument\n");
+                       break;
+               }
+       }
+
+       return;
+
+ found_cmd:
+       script_args_end = j;
+       forks = 1;
+       workload_argv = &argv[j + 1];
+}
+
+static void compile(const char *input)
+{
+       ktap_closure *cl;
+       char *buff;
+       struct stat sb;
+       int fdin;
+
+       if (oneline_src[0] != '\0') {
+               init_dummy_global_state();
+               cl = ktapc_parser(oneline_src, input);
+               goto dump;
+       }
+
+       fdin = open(input, O_RDONLY);
+       if (fdin < 0) {
+               fprintf(stderr, "open file %s failed\n", input);
+               exit(-1);
+       }
+
+       if (fstat(fdin, &sb) == -1)
+               handle_error("fstat failed");
+
+       buff = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fdin, 0);
+       if (buff == MAP_FAILED)
+               handle_error("mmap failed");
+
+       init_dummy_global_state();
+       cl = ktapc_parser(buff, input);
+
+       munmap(buff, sb.st_size);
+       close(fdin);
+
+ dump:
+       if (dump_bytecode) {
+               dump_function(1, cl->l.p);
+               exit(0);
+       }
+
+       /* ktapc output */
+       uparm.trunk = malloc(ktap_trunk_mem_size);
+       if (!uparm.trunk)
+               handle_error("malloc failed");
+
+       ktapc_dump(cl->l.p, ktapc_writer, NULL, 0);
+}
+
+int main(int argc, char **argv)
+{
+       char **ktapvm_argv;
+       int new_index, i;
+       int ret;
+
+       if (argc == 1)
+               usage("");
+
+       parse_option(argc, argv);
+
+       if (oneline_src[0] != '\0')
+               script_file = "one-liner";
+
+       compile(script_file);
+
+       ktapvm_argv = (char **)malloc(sizeof(char *)*(script_args_end -
+                                       script_args_start + 1));
+       if (!ktapvm_argv) {
+               fprintf(stderr, "canno allocate ktapvm_argv\n");
+               return -1;
+       }
+
+       ktapvm_argv[0] = malloc(strlen(script_file) + 1);
+       if (!ktapvm_argv[0]) {
+               fprintf(stderr, "canno allocate memory\n");
+               return -1;
+       }
+       strcpy(ktapvm_argv[0], script_file);
+       ktapvm_argv[0][strlen(script_file)] = '\0';
+
+       /* pass rest argv into ktapvm */
+       new_index = 1;
+       for (i = script_args_start; i < script_args_end; i++) {
+               ktapvm_argv[new_index] = malloc(strlen(argv[i]) + 1);
+               if (!ktapvm_argv[new_index]) {
+                       fprintf(stderr, "canno allocate memory\n");
+                       return -1;
+               }
+               strcpy(ktapvm_argv[new_index], argv[i]);
+               ktapvm_argv[new_index][strlen(argv[i])] = '\0';
+               new_index++;
+       }
+
+       uparm.argv = ktapvm_argv;
+       uparm.argc = new_index;
+       uparm.verbose = verbose;
+       uparm.trace_pid = trace_pid;
+       uparm.trace_cpu = trace_cpu;
+       uparm.print_timestamp = print_timestamp;
+
+       /* start running into kernel ktapvm */
+       ret = run_ktapvm();
+
+       cleanup_event_resources();
+       return ret;
+}
+
+
diff --git a/drivers/staging/ktap/userspace/parser.c b/drivers/staging/ktap/userspace/parser.c
new file mode 100644 (file)
index 0000000..dd9e2de
--- /dev/null
@@ -0,0 +1,1910 @@
+/*
+ * parser.c - ktap parser
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../include/ktap_types.h"
+#include "../include/ktap_opcodes.h"
+#include "ktapc.h"
+
+/* maximum number of local variables per function (must be smaller
+   than 250, due to the bytecode format) */
+#define MAXVARS                200
+
+#define hasmultret(k)          ((k) == VCALL || (k) == VVARARG)
+
+
+/*
+ * nodes for block list (list of active blocks)
+ */
+typedef struct ktap_blockcnt {
+       struct ktap_blockcnt *previous;  /* chain */
+       short firstlabel;  /* index of first label in this block */
+       short firstgoto;  /* index of first pending goto in this block */
+       u8 nactvar;  /* # active locals outside the block */
+       u8 upval;  /* true if some variable in the block is an upvalue */
+        u8 isloop;  /* true if `block' is a loop */
+} ktap_blockcnt;
+
+/*
+ * prototypes for recursive non-terminal functions
+ */
+static void statement (ktap_lexstate *ls);
+static void expr (ktap_lexstate *ls, ktap_expdesc *v);
+
+static void anchor_token(ktap_lexstate *ls)
+{
+       /* last token from outer function must be EOS */
+       ktap_assert((int)(ls->fs != NULL) || ls->t.token == TK_EOS);
+       if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
+               ktap_string *ts = ls->t.seminfo.ts;
+               lex_newstring(ls, getstr(ts), ts->tsv.len);
+       }
+}
+
+/* semantic error */
+static void semerror(ktap_lexstate *ls, const char *msg)
+{
+       ls->t.token = 0;  /* remove 'near to' from final message */
+       lex_syntaxerror(ls, msg);
+}
+
+static void error_expected(ktap_lexstate *ls, int token)
+{
+       lex_syntaxerror(ls,
+               ktapc_sprintf("%s expected", lex_token2str(ls, token)));
+}
+
+static void errorlimit(ktap_funcstate *fs, int limit, const char *what)
+{
+       const char *msg;
+       int line = fs->f->linedefined;
+       const char *where = (line == 0) ? "main function"
+                               : ktapc_sprintf("function at line %d", line);
+
+       msg = ktapc_sprintf("too many %s (limit is %d) in %s",
+                               what, limit, where);
+       lex_syntaxerror(fs->ls, msg);
+}
+
+static void checklimit(ktap_funcstate *fs, int v, int l, const char *what)
+{
+       if (v > l)
+               errorlimit(fs, l, what);
+}
+
+static int testnext(ktap_lexstate *ls, int c)
+{
+       if (ls->t.token == c) {
+               lex_next(ls);
+               return 1;
+       }
+       else
+               return 0;
+}
+
+static void check(ktap_lexstate *ls, int c)
+{
+       if (ls->t.token != c)
+               error_expected(ls, c);
+}
+
+static void checknext(ktap_lexstate *ls, int c)
+{
+       check(ls, c);
+       lex_next(ls);
+}
+
+#define check_condition(ls,c,msg)      { if (!(c)) lex_syntaxerror(ls, msg); }
+
+static void check_match(ktap_lexstate *ls, int what, int who, int where)
+{
+       if (!testnext(ls, what)) {
+               if (where == ls->linenumber)
+                       error_expected(ls, what);
+               else {
+                       lex_syntaxerror(ls, ktapc_sprintf(
+                                       "%s expected (to close %s at line %d)",
+                                       lex_token2str(ls, what),
+                                       lex_token2str(ls, who), where));
+               }
+       }
+}
+
+static ktap_string *str_checkname(ktap_lexstate *ls)
+{
+       ktap_string *ts;
+
+       check(ls, TK_NAME);
+       ts = ls->t.seminfo.ts;
+       lex_next(ls);
+       return ts;
+}
+
+static void init_exp(ktap_expdesc *e, expkind k, int i)
+{
+       e->f = e->t = NO_JUMP;
+       e->k = k;
+       e->u.info = i;
+}
+
+static void codestring(ktap_lexstate *ls, ktap_expdesc *e, ktap_string *s)
+{
+       init_exp(e, VK, codegen_stringK(ls->fs, s));
+}
+
+static void checkname(ktap_lexstate *ls, ktap_expdesc *e)
+{
+       codestring(ls, e, str_checkname(ls));
+}
+
+static int registerlocalvar(ktap_lexstate *ls, ktap_string *varname)
+{
+       ktap_funcstate *fs = ls->fs;
+       ktap_proto *f = fs->f;
+       int oldsize = f->sizelocvars;
+
+       ktapc_growvector(f->locvars, fs->nlocvars, f->sizelocvars,
+                        ktap_locvar, SHRT_MAX, "local variables");
+
+       while (oldsize < f->sizelocvars)
+               f->locvars[oldsize++].varname = NULL;
+
+       f->locvars[fs->nlocvars].varname = varname;
+       return fs->nlocvars++;
+}
+
+static void new_localvar(ktap_lexstate *ls, ktap_string *name)
+{
+       ktap_funcstate *fs = ls->fs;
+       ktap_dyndata *dyd = ls->dyd;
+       int reg = registerlocalvar(ls, name);
+
+       checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
+                  MAXVARS, "local variables");
+       ktapc_growvector(dyd->actvar.arr, dyd->actvar.n + 1,
+                        dyd->actvar.size, ktap_vardesc, MAX_INT, "local variables");
+       dyd->actvar.arr[dyd->actvar.n++].idx = (short)reg;
+}
+
+static void new_localvarliteral_(ktap_lexstate *ls, const char *name, size_t sz)
+{
+       new_localvar(ls, lex_newstring(ls, name, sz));
+}
+
+#define new_localvarliteral(ls,v) \
+       new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1)
+
+static ktap_locvar *getlocvar(ktap_funcstate *fs, int i)
+{
+       int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
+
+       ktap_assert(idx < fs->nlocvars);
+       return &fs->f->locvars[idx];
+}
+
+static void adjustlocalvars(ktap_lexstate *ls, int nvars)
+{
+       ktap_funcstate *fs = ls->fs;
+
+       fs->nactvar = (u8)(fs->nactvar + nvars);
+       for (; nvars; nvars--) {
+               getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;
+       }
+}
+
+static void removevars(ktap_funcstate *fs, int tolevel)
+{
+       fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
+
+       while (fs->nactvar > tolevel)
+               getlocvar(fs, --fs->nactvar)->endpc = fs->pc;
+}
+
+static int searchupvalue(ktap_funcstate *fs, ktap_string *name)
+{
+       int i;
+       ktap_upvaldesc *up = fs->f->upvalues;
+
+       for (i = 0; i < fs->nups; i++) {
+               if (ktapc_ts_eqstr(up[i].name, name))
+                       return i;
+       }
+       return -1;  /* not found */
+}
+
+static int newupvalue(ktap_funcstate *fs, ktap_string *name, ktap_expdesc *v)
+{
+       ktap_proto *f = fs->f;
+       int oldsize = f->sizeupvalues;
+
+       checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
+       ktapc_growvector(f->upvalues, fs->nups, f->sizeupvalues,
+                        ktap_upvaldesc, MAXUPVAL, "upvalues");
+
+       while (oldsize < f->sizeupvalues)
+               f->upvalues[oldsize++].name = NULL;
+       f->upvalues[(int)fs->nups].instack = (v->k == VLOCAL);
+       f->upvalues[(int)fs->nups].idx = (u8)(v->u.info);
+       f->upvalues[(int)fs->nups].name = name;
+       return fs->nups++;
+}
+
+static int searchvar(ktap_funcstate *fs, ktap_string *n)
+{
+       int i;
+
+       for (i = fs->nactvar-1; i >= 0; i--) {
+               if (ktapc_ts_eqstr(n, getlocvar(fs, i)->varname))
+                       return i;
+       }
+       return -1;  /* not found */
+}
+
+/*
+ * Mark block where variable at given level was defined
+ * (to emit close instructions later).
+ */
+static void markupval(ktap_funcstate *fs, int level)
+{
+       ktap_blockcnt *bl = fs->bl;
+
+       while (bl->nactvar > level)
+               bl = bl->previous;
+       bl->upval = 1;
+}
+
+/*
+ * Find variable with given name 'n'. If it is an upvalue, add this
+ * upvalue into all intermediate functions.
+ */
+static int singlevaraux(ktap_funcstate *fs, ktap_string *n, ktap_expdesc *var, int base)
+{
+       if (fs == NULL)  /* no more levels? */
+               return VVOID;  /* default is global */
+       else {
+               int v = searchvar(fs, n);  /* look up locals at current level */
+               if (v >= 0) {  /* found? */
+                       init_exp(var, VLOCAL, v);  /* variable is local */
+                       if (!base)
+                               markupval(fs, v);  /* local will be used as an upval */
+                       return VLOCAL;
+               } else {  /* not found as local at current level; try upvalues */
+                       int idx = searchupvalue(fs, n);  /* try existing upvalues */
+                       if (idx < 0) {  /* not found? */
+                               if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
+                                       return VVOID;  /* not found; is a global */
+                               /* else was LOCAL or UPVAL */
+                               idx  = newupvalue(fs, n, var);  /* will be a new upvalue */
+                       }
+                       init_exp(var, VUPVAL, idx);
+                       return VUPVAL;
+               }
+       }
+}
+
+static void singlevar(ktap_lexstate *ls, ktap_expdesc *var)
+{
+       ktap_string *varname = str_checkname(ls);
+       ktap_funcstate *fs = ls->fs;
+
+       if (singlevaraux(fs, varname, var, 1) == VVOID) {  /* global name? */
+               ktap_expdesc key;
+               singlevaraux(fs, ls->envn, var, 1);  /* get environment variable */
+               ktap_assert(var->k == VLOCAL || var->k == VUPVAL);
+               codestring(ls, &key, varname);  /* key is variable name */
+               codegen_indexed(fs, var, &key);  /* env[varname] */
+       }
+}
+
+static void adjust_assign(ktap_lexstate *ls, int nvars, int nexps, ktap_expdesc *e)
+{
+       ktap_funcstate *fs = ls->fs;
+       int extra = nvars - nexps;
+
+       if (hasmultret(e->k)) {
+               extra++;  /* includes call itself */
+               if (extra < 0)
+                       extra = 0;
+               codegen_setreturns(fs, e, extra);  /* last exp. provides the difference */
+               if (extra > 1)
+                       codegen_reserveregs(fs, extra-1);
+       } else {
+               if (e->k != VVOID)
+                       codegen_exp2nextreg(fs, e);  /* close last expression */
+               if (extra > 0) {
+                       int reg = fs->freereg;
+
+                       codegen_reserveregs(fs, extra);
+                       codegen_nil(fs, reg, extra);
+               }
+       }
+}
+
+static void enterlevel(ktap_lexstate *ls)
+{
+       ++ls->nCcalls;
+       checklimit(ls->fs, ls->nCcalls, KTAP_MAXCCALLS, "C levels");
+}
+
+static void closegoto(ktap_lexstate *ls, int g, ktap_labeldesc *label)
+{
+       int i;
+       ktap_funcstate *fs = ls->fs;
+       ktap_labellist *gl = &ls->dyd->gt;
+       ktap_labeldesc *gt = &gl->arr[g];
+
+       ktap_assert(ktapc_ts_eqstr(gt->name, label->name));
+       if (gt->nactvar < label->nactvar) {
+               ktap_string *vname = getlocvar(fs, gt->nactvar)->varname;
+               const char *msg = ktapc_sprintf(
+                       "<goto %s> at line %d jumps into the scope of local " KTAP_QS,
+                       getstr(gt->name), gt->line, getstr(vname));
+               semerror(ls, msg);
+       }
+
+       codegen_patchlist(fs, gt->pc, label->pc);
+       /* remove goto from pending list */
+       for (i = g; i < gl->n - 1; i++)
+               gl->arr[i] = gl->arr[i + 1];
+       gl->n--;
+}
+
+/*
+ * try to close a goto with existing labels; this solves backward jumps
+ */
+static int findlabel(ktap_lexstate *ls, int g)
+{
+       int i;
+       ktap_blockcnt *bl = ls->fs->bl;
+       ktap_dyndata *dyd = ls->dyd;
+       ktap_labeldesc *gt = &dyd->gt.arr[g];
+
+       /* check labels in current block for a match */
+       for (i = bl->firstlabel; i < dyd->label.n; i++) {
+               ktap_labeldesc *lb = &dyd->label.arr[i];
+               if (ktapc_ts_eqstr(lb->name, gt->name)) {  /* correct label? */
+                       if (gt->nactvar > lb->nactvar &&
+                               (bl->upval || dyd->label.n > bl->firstlabel))
+                               codegen_patchclose(ls->fs, gt->pc, lb->nactvar);
+                       closegoto(ls, g, lb);  /* close it */
+                       return 1;
+               }
+       }
+       return 0;  /* label not found; cannot close goto */
+}
+
+static int newlabelentry(ktap_lexstate *ls, ktap_labellist *l, ktap_string *name,
+                        int line, int pc)
+{
+       int n = l->n;
+
+       ktapc_growvector(l->arr, n, l->size,
+                        ktap_labeldesc, SHRT_MAX, "labels/gotos");
+       l->arr[n].name = name;
+       l->arr[n].line = line;
+       l->arr[n].nactvar = ls->fs->nactvar;
+       l->arr[n].pc = pc;
+       l->n++;
+       return n;
+}
+
+
+/*
+ * check whether new label 'lb' matches any pending gotos in current
+ * block; solves forward jumps
+ */
+static void findgotos(ktap_lexstate *ls, ktap_labeldesc *lb)
+{
+       ktap_labellist *gl = &ls->dyd->gt;
+       int i = ls->fs->bl->firstgoto;
+
+       while (i < gl->n) {
+               if (ktapc_ts_eqstr(gl->arr[i].name, lb->name))
+                       closegoto(ls, i, lb);
+               else
+                       i++;
+       }
+}
+
+/*
+ * "export" pending gotos to outer level, to check them against
+ * outer labels; if the block being exited has upvalues, and
+ * the goto exits the scope of any variable (which can be the
+ * upvalue), close those variables being exited.
+ */
+static void movegotosout(ktap_funcstate *fs, ktap_blockcnt *bl)
+{
+       int i = bl->firstgoto;
+       ktap_labellist *gl = &fs->ls->dyd->gt;
+
+       /* correct pending gotos to current block and try to close it
+               with visible labels */
+       while (i < gl->n) {
+               ktap_labeldesc *gt = &gl->arr[i];
+
+               if (gt->nactvar > bl->nactvar) {
+                       if (bl->upval)
+                               codegen_patchclose(fs, gt->pc, bl->nactvar);
+                       gt->nactvar = bl->nactvar;
+               }
+               if (!findlabel(fs->ls, i))
+                       i++;  /* move to next one */
+       }
+}
+
+static void enterblock(ktap_funcstate *fs, ktap_blockcnt *bl, u8 isloop)
+{
+       bl->isloop = isloop;
+       bl->nactvar = fs->nactvar;
+       bl->firstlabel = fs->ls->dyd->label.n;
+       bl->firstgoto = fs->ls->dyd->gt.n;
+       bl->upval = 0;
+       bl->previous = fs->bl;
+       fs->bl = bl;
+       ktap_assert(fs->freereg == fs->nactvar);
+}
+
+
+/*
+ * create a label named "break" to resolve break statements
+ */
+static void breaklabel(ktap_lexstate *ls)
+{
+       ktap_string *n = ktapc_ts_new("break");
+       int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc);
+
+       findgotos(ls, &ls->dyd->label.arr[l]);
+}
+
+/*
+ * generates an error for an undefined 'goto'; choose appropriate
+ * message when label name is a reserved word (which can only be 'break')
+ */
+static void undefgoto(ktap_lexstate *ls, ktap_labeldesc *gt)
+{
+       const char *msg = isreserved(gt->name)
+                       ? "<%s> at line %d not inside a loop"
+                       : "no visible label " KTAP_QS " for <goto> at line %d";
+
+       msg = ktapc_sprintf(msg, getstr(gt->name), gt->line);
+       semerror(ls, msg);
+}
+
+static void leaveblock(ktap_funcstate *fs)
+{
+       ktap_blockcnt *bl = fs->bl;
+       ktap_lexstate *ls = fs->ls;
+       if (bl->previous && bl->upval) {
+               /* create a 'jump to here' to close upvalues */
+               int j = codegen_jump(fs);
+
+               codegen_patchclose(fs, j, bl->nactvar);
+               codegen_patchtohere(fs, j);
+       }
+
+       if (bl->isloop)
+               breaklabel(ls);  /* close pending breaks */
+
+       fs->bl = bl->previous;
+       removevars(fs, bl->nactvar);
+       ktap_assert(bl->nactvar == fs->nactvar);
+       fs->freereg = fs->nactvar;  /* free registers */
+       ls->dyd->label.n = bl->firstlabel;  /* remove local labels */
+       if (bl->previous)  /* inner block? */
+               movegotosout(fs, bl);  /* update pending gotos to outer block */
+       else if (bl->firstgoto < ls->dyd->gt.n)  /* pending gotos in outer block? */
+               undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]);  /* error */
+}
+
+/*
+ * adds a new prototype into list of prototypes
+ */
+static ktap_proto *addprototype(ktap_lexstate *ls)
+{
+       ktap_proto *clp;
+       ktap_funcstate *fs = ls->fs;
+       ktap_proto *f = fs->f;  /* prototype of current function */
+
+       if (fs->np >= f->sizep) {
+               int oldsize = f->sizep;
+               ktapc_growvector(f->p, fs->np, f->sizep, ktap_proto *, MAXARG_Bx, "functions");
+               while (oldsize < f->sizep)
+                       f->p[oldsize++] = NULL;
+       }
+       f->p[fs->np++] = clp = ktapc_newproto();
+       return clp;
+}
+
+/*
+ * codes instruction to create new closure in parent function
+ */
+static void codeclosure(ktap_lexstate *ls, ktap_expdesc *v)
+{
+       ktap_funcstate *fs = ls->fs->prev;
+       init_exp(v, VRELOCABLE, codegen_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
+       codegen_exp2nextreg(fs, v);  /* fix it at stack top (for GC) */
+}
+
+static void open_func(ktap_lexstate *ls, ktap_funcstate *fs, ktap_blockcnt *bl)
+{
+       ktap_proto *f;
+
+       fs->prev = ls->fs;  /* linked list of funcstates */
+       fs->ls = ls;
+       ls->fs = fs;
+       fs->pc = 0;
+       fs->lasttarget = 0;
+       fs->jpc = NO_JUMP;
+       fs->freereg = 0;
+       fs->nk = 0;
+       fs->np = 0;
+       fs->nups = 0;
+       fs->nlocvars = 0;
+       fs->nactvar = 0;
+       fs->firstlocal = ls->dyd->actvar.n;
+       fs->bl = NULL;
+       f = fs->f;
+       f->source = ls->source;
+       f->maxstacksize = 2;  /* registers 0/1 are always valid */
+       fs->h = ktapc_table_new();
+       //table_resize(NULL, fs->h, 32, 32);
+       enterblock(fs, bl, 0);
+}
+
+static void close_func(ktap_lexstate *ls)
+{
+       ktap_funcstate *fs = ls->fs;
+       ktap_proto *f = fs->f;
+
+       codegen_ret(fs, 0, 0);  /* final return */
+       leaveblock(fs);
+       ktapc_reallocvector(f->code, f->sizecode, fs->pc, ktap_instruction);
+       f->sizecode = fs->pc;
+       ktapc_reallocvector(f->lineinfo, f->sizelineinfo, fs->pc, int);
+       f->sizelineinfo = fs->pc;
+       ktapc_reallocvector(f->k, f->sizek, fs->nk, ktap_value);
+       f->sizek = fs->nk;
+       ktapc_reallocvector(f->p, f->sizep, fs->np, ktap_proto *);
+       f->sizep = fs->np;
+       ktapc_reallocvector(f->locvars, f->sizelocvars, fs->nlocvars, ktap_locvar);
+       f->sizelocvars = fs->nlocvars;
+       ktapc_reallocvector(f->upvalues, f->sizeupvalues, fs->nups, ktap_upvaldesc);
+       f->sizeupvalues = fs->nups;
+       ktap_assert((int)(fs->bl == NULL));
+       ls->fs = fs->prev;
+       /* last token read was anchored in defunct function; must re-anchor it */
+       anchor_token(ls);
+}
+
+/*============================================================*/
+/* GRAMMAR RULES */
+/*============================================================*/
+
+/*
+ * check whether current token is in the follow set of a block.
+ * 'until' closes syntactical blocks, but do not close scope,
+ * so it handled in separate.
+ */
+static int block_follow(ktap_lexstate *ls, int withuntil)
+{
+       switch (ls->t.token) {
+       case TK_ELSE: case TK_ELSEIF:
+       case TK_END: case TK_EOS:
+               return 1;
+       case TK_UNTIL:
+               return withuntil;
+       case '}':
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static void statlist(ktap_lexstate *ls)
+{
+       /* statlist -> { stat [`;'] } */
+       while (!block_follow(ls, 1)) {
+               if (ls->t.token == TK_RETURN) {
+                       statement(ls);
+                       return;  /* 'return' must be last statement */
+               }
+               statement(ls);
+       }
+}
+
+static void fieldsel(ktap_lexstate *ls, ktap_expdesc *v)
+{
+       /* fieldsel -> ['.' | ':'] NAME */
+       ktap_funcstate *fs = ls->fs;
+       ktap_expdesc key;
+
+       codegen_exp2anyregup(fs, v);
+       lex_next(ls);  /* skip the dot or colon */
+       checkname(ls, &key);
+       codegen_indexed(fs, v, &key);
+}
+
+static void yindex(ktap_lexstate *ls, ktap_expdesc *v)
+{
+       /* index -> '[' expr ']' */
+       lex_next(ls);  /* skip the '[' */
+       expr(ls, v);
+       codegen_exp2val(ls->fs, v);
+       checknext(ls, ']');
+}
+
+/*
+ * {======================================================================
+ * Rules for Constructors
+ * =======================================================================
+ */
+struct ConsControl {
+       ktap_expdesc v;  /* last list item read */
+       ktap_expdesc *t;  /* table descriptor */
+       int nh;  /* total number of `record' elements */
+       int na;  /* total number of array elements */
+       int tostore;  /* number of array elements pending to be stored */
+};
+
+static void recfield(ktap_lexstate *ls, struct ConsControl *cc)
+{
+       /* recfield -> (NAME | `['exp1`]') = exp1 */
+       ktap_funcstate *fs = ls->fs;
+       int reg = ls->fs->freereg;
+       ktap_expdesc key, val;
+       int rkkey;
+
+       if (ls->t.token == TK_NAME) {
+               checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
+               checkname(ls, &key);
+       } else  /* ls->t.token == '[' */
+               yindex(ls, &key);
+
+       cc->nh++;
+       checknext(ls, '=');
+       rkkey = codegen_exp2RK(fs, &key);
+       expr(ls, &val);
+       codegen_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, codegen_exp2RK(fs, &val));
+       fs->freereg = reg;  /* free registers */
+}
+
+static void closelistfield(ktap_funcstate *fs, struct ConsControl *cc)
+{
+       if (cc->v.k == VVOID)
+               return;  /* there is no list item */
+       codegen_exp2nextreg(fs, &cc->v);
+       cc->v.k = VVOID;
+       if (cc->tostore == LFIELDS_PER_FLUSH) {
+               codegen_setlist(fs, cc->t->u.info, cc->na, cc->tostore);  /* flush */
+               cc->tostore = 0;  /* no more items pending */
+       }
+}
+
+static void lastlistfield(ktap_funcstate *fs, struct ConsControl *cc)
+{
+       if (cc->tostore == 0)
+               return;
+
+       if (hasmultret(cc->v.k)) {
+               codegen_setmultret(fs, &cc->v);
+               codegen_setlist(fs, cc->t->u.info, cc->na, KTAP_MULTRET);
+               cc->na--;  /* do not count last expression (unknown number of elements) */
+       } else {
+               if (cc->v.k != VVOID)
+                       codegen_exp2nextreg(fs, &cc->v);
+               codegen_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
+       }
+}
+
+static void listfield(ktap_lexstate *ls, struct ConsControl *cc)
+{
+       /* listfield -> exp */
+       expr(ls, &cc->v);
+       checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
+       cc->na++;
+       cc->tostore++;
+}
+
+static void field(ktap_lexstate *ls, struct ConsControl *cc)
+{
+       /* field -> listfield | recfield */
+       switch(ls->t.token) {
+       case TK_NAME: {  /* may be 'listfield' or 'recfield' */
+               if (lex_lookahead(ls) != '=')  /* expression? */
+                       listfield(ls, cc);
+               else
+                       recfield(ls, cc);
+               break;
+       }
+       case '[': {
+               recfield(ls, cc);
+               break;
+       }
+       default:
+               listfield(ls, cc);
+               break;
+       }
+}
+
+static void constructor(ktap_lexstate *ls, ktap_expdesc *t)
+{
+       /* constructor -> '{' [ field { sep field } [sep] ] '}'
+               sep -> ',' | ';' */
+       ktap_funcstate *fs = ls->fs;
+       int line = ls->linenumber;
+       int pc = codegen_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
+       struct ConsControl cc;
+
+       cc.na = cc.nh = cc.tostore = 0;
+       cc.t = t;
+       init_exp(t, VRELOCABLE, pc);
+       init_exp(&cc.v, VVOID, 0);  /* no value (yet) */
+       codegen_exp2nextreg(ls->fs, t);  /* fix it at stack top */
+       checknext(ls, '{');
+       do {
+               ktap_assert(cc.v.k == VVOID || cc.tostore > 0);
+               if (ls->t.token == '}')
+                       break;
+               closelistfield(fs, &cc);
+               field(ls, &cc);
+       } while (testnext(ls, ',') || testnext(ls, ';'));
+       check_match(ls, '}', '{', line);
+       lastlistfield(fs, &cc);
+       SETARG_B(fs->f->code[pc], ktapc_int2fb(cc.na)); /* set initial array size */
+       SETARG_C(fs->f->code[pc], ktapc_int2fb(cc.nh));  /* set initial table size */
+}
+
+/* }====================================================================== */
+
+static void parlist(ktap_lexstate *ls)
+{
+       /* parlist -> [ param { `,' param } ] */
+       ktap_funcstate *fs = ls->fs;
+       ktap_proto *f = fs->f;
+       int nparams = 0;
+       f->is_vararg = 0;
+
+       if (ls->t.token != ')') {  /* is `parlist' not empty? */
+               do {
+                       switch (ls->t.token) {
+                       case TK_NAME: {  /* param -> NAME */
+                               new_localvar(ls, str_checkname(ls));
+                               nparams++;
+                               break;
+                       }
+                       case TK_DOTS: {  /* param -> `...' */
+                               lex_next(ls);
+                               f->is_vararg = 1;
+                               break;
+                       }
+                       default:
+                               lex_syntaxerror(ls, "<name> or " KTAP_QL("...") " expected");
+                       }
+               } while (!f->is_vararg && testnext(ls, ','));
+       }
+       adjustlocalvars(ls, nparams);
+       f->numparams = (u8)(fs->nactvar);
+       codegen_reserveregs(fs, fs->nactvar);  /* reserve register for parameters */
+}
+
+static void body(ktap_lexstate *ls, ktap_expdesc *e, int ismethod, int line)
+{
+       /* body ->  `(' parlist `)' block END */
+       ktap_funcstate new_fs;
+       ktap_blockcnt bl;
+
+       new_fs.f = addprototype(ls);
+       new_fs.f->linedefined = line;
+       open_func(ls, &new_fs, &bl);
+       checknext(ls, '(');
+       if (ismethod) {
+               new_localvarliteral(ls, "self");  /* create 'self' parameter */
+               adjustlocalvars(ls, 1);
+       }
+       parlist(ls);
+       checknext(ls, ')');
+       checknext(ls, '{');
+       statlist(ls);
+       new_fs.f->lastlinedefined = ls->linenumber;
+       checknext(ls, '}');
+       //check_match(ls, TK_END, TK_FUNCTION, line);
+       codeclosure(ls, e);
+       close_func(ls);
+}
+
+static void func_body_no_args(ktap_lexstate *ls, ktap_expdesc *e, int line)
+{
+       /* body ->  `(' parlist `)' block END */
+       ktap_funcstate new_fs;
+       ktap_blockcnt bl;
+
+       new_fs.f = addprototype(ls);
+       new_fs.f->linedefined = line;
+       open_func(ls, &new_fs, &bl);
+       checknext(ls, '{');
+       statlist(ls);
+       new_fs.f->lastlinedefined = ls->linenumber;
+       checknext(ls, '}');
+       //check_match(ls, TK_END, TK_FUNCTION, line);
+       codeclosure(ls, e);
+       close_func(ls);
+}
+
+static int explist(ktap_lexstate *ls, ktap_expdesc *v)
+{
+       /* explist -> expr { `,' expr } */
+       int n = 1;  /* at least one expression */
+
+       expr(ls, v);
+       while (testnext(ls, ',')) {
+               codegen_exp2nextreg(ls->fs, v);
+               expr(ls, v);
+               n++;
+       }
+       return n;
+}
+
+static void funcargs(ktap_lexstate *ls, ktap_expdesc *f, int line)
+{
+       ktap_funcstate *fs = ls->fs;
+       ktap_expdesc args;
+       int base, nparams;
+
+       switch (ls->t.token) {
+       case '(': {  /* funcargs -> `(' [ explist ] `)' */
+               lex_next(ls);
+               if (ls->t.token == ')')  /* arg list is empty? */
+                       args.k = VVOID;
+               else {
+                       explist(ls, &args);
+                       codegen_setmultret(fs, &args);
+               }
+               check_match(ls, ')', '(', line);
+               break;
+       }
+       case '{': {  /* funcargs -> constructor */
+               constructor(ls, &args);
+               break;
+       }
+       case TK_STRING: {  /* funcargs -> STRING */
+               codestring(ls, &args, ls->t.seminfo.ts);
+               lex_next(ls);  /* must use `seminfo' before `next' */
+               break;
+       }
+       default: {
+               lex_syntaxerror(ls, "function arguments expected");
+       }
+       }
+       ktap_assert(f->k == VNONRELOC);
+       base = f->u.info;  /* base register for call */
+       if (hasmultret(args.k))
+               nparams = KTAP_MULTRET;  /* open call */
+       else {
+               if (args.k != VVOID)
+                       codegen_exp2nextreg(fs, &args);  /* close last argument */
+               nparams = fs->freereg - (base+1);
+       }
+       init_exp(f, VCALL, codegen_codeABC(fs, OP_CALL, base, nparams+1, 2));
+       codegen_fixline(fs, line);
+       fs->freereg = base+1;  /* call remove function and arguments and leaves
+                               (unless changed) one result */
+}
+
+/*
+ * {======================================================================
+ * Expression parsing
+ * =======================================================================
+ */
+static void primaryexp(ktap_lexstate *ls, ktap_expdesc *v)
+{
+       /* primaryexp -> NAME | '(' expr ')' */
+       switch (ls->t.token) {
+       case '(': {
+               int line = ls->linenumber;
+
+               lex_next(ls);
+               expr(ls, v);
+               check_match(ls, ')', '(', line);
+               codegen_dischargevars(ls->fs, v);
+               return;
+       }
+       case TK_NAME:
+               singlevar(ls, v);
+               return;
+       default:
+               lex_syntaxerror(ls, "unexpected symbol");
+       }
+}
+
+static void suffixedexp(ktap_lexstate *ls, ktap_expdesc *v)
+{
+       /* suffixedexp ->
+               primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
+       ktap_funcstate *fs = ls->fs;
+       int line = ls->linenumber;
+
+       primaryexp(ls, v);
+       for (;;) {
+               switch (ls->t.token) {
+               case '.': {  /* fieldsel */
+                       fieldsel(ls, v);
+                       break;
+               }
+               case '[': {  /* `[' exp1 `]' */
+                       ktap_expdesc key;
+                       codegen_exp2anyregup(fs, v);
+                       yindex(ls, &key);
+                       codegen_indexed(fs, v, &key);
+                       break;
+               }
+               case ':': {  /* `:' NAME funcargs */
+                       ktap_expdesc key;
+                       lex_next(ls);
+                       checkname(ls, &key);
+                       codegen_self(fs, v, &key);
+                       funcargs(ls, v, line);
+                       break;
+               }
+               case '(': case TK_STRING: case '{': {  /* funcargs */
+                       codegen_exp2nextreg(fs, v);
+                       funcargs(ls, v, line);
+                       break;
+               }
+               default:
+                       return;
+               }
+       }
+}
+
+static void simpleexp(ktap_lexstate *ls, ktap_expdesc *v)
+{
+       /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
+               constructor | FUNCTION body | suffixedexp */
+       switch (ls->t.token) {
+       case TK_NUMBER: {
+               init_exp(v, VKNUM, 0);
+               v->u.nval = ls->t.seminfo.r;
+               break;
+       }
+       case TK_STRING: {
+               codestring(ls, v, ls->t.seminfo.ts);
+               break;
+       }
+       case TK_NIL: {
+               init_exp(v, VNIL, 0);
+               break;
+       }
+       case TK_TRUE: {
+               init_exp(v, VTRUE, 0);
+               break;
+       }
+       case TK_FALSE: {
+               init_exp(v, VFALSE, 0);
+               break;
+       }
+       case TK_DOTS: {  /* vararg */
+               ktap_funcstate *fs = ls->fs;
+               check_condition(ls, fs->f->is_vararg,
+                      "cannot use " KTAP_QL("...") " outside a vararg function");
+               init_exp(v, VVARARG, codegen_codeABC(fs, OP_VARARG, 0, 1, 0));
+               break;
+       }
+       case '{': {  /* constructor */
+               constructor(ls, v);
+               return;
+       }
+       case TK_FUNCTION: {
+               lex_next(ls);
+               body(ls, v, 0, ls->linenumber);
+               return;
+       }
+       case TK_ARGEVENT:
+               init_exp(v, VEVENT, 0);
+               break;
+
+       case TK_ARGNAME:
+               init_exp(v, VEVENTNAME, 0);
+               break;
+       case TK_ARG1:
+       case TK_ARG2:
+       case TK_ARG3:
+       case TK_ARG4:
+       case TK_ARG5:
+       case TK_ARG6:
+       case TK_ARG7:
+       case TK_ARG8:
+       case TK_ARG9:
+               init_exp(v, VEVENTARG, ls->t.token - TK_ARG1 + 1);
+               break;
+       default: {
+               suffixedexp(ls, v);
+               return;
+       }
+       }
+       lex_next(ls);
+}
+
+static UnOpr getunopr(int op)
+{
+       switch (op) {
+       case TK_NOT: return OPR_NOT;
+       case '-': return OPR_MINUS;
+       case '#': return OPR_LEN;
+       default: return OPR_NOUNOPR;
+       }
+}
+
+static BinOpr getbinopr(int op)
+{
+       switch (op) {
+       case '+': return OPR_ADD;
+       case '-': return OPR_SUB;
+       case '*': return OPR_MUL;
+       case '/': return OPR_DIV;
+       case '%': return OPR_MOD;
+       case '^': return OPR_POW;
+       case TK_CONCAT: return OPR_CONCAT;
+       case TK_NE: return OPR_NE;
+       case TK_EQ: return OPR_EQ;
+       case '<': return OPR_LT;
+       case TK_LE: return OPR_LE;
+       case '>': return OPR_GT;
+       case TK_GE: return OPR_GE;
+       case TK_AND: return OPR_AND;
+       case TK_OR: return OPR_OR;
+       default: return OPR_NOBINOPR;
+       }
+}
+
+static const struct {
+       u8 left;  /* left priority for each binary operator */
+       u8 right; /* right priority */
+} priority[] = {  /* ORDER OPR */
+       {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7},  /* `+' `-' `*' `/' `%' */
+       {10, 9}, {5, 4},                 /* ^, .. (right associative) */
+       {3, 3}, {3, 3}, {3, 3},          /* ==, <, <= */
+       {3, 3}, {3, 3}, {3, 3},          /* !=, >, >= */
+       {2, 2}, {1, 1}                   /* and, or */
+};
+
+#define UNARY_PRIORITY 8  /* priority for unary operators */
+
+#define leavelevel(ls) (ls->nCcalls--)
+
+/*
+ * subexpr -> (simpleexp | unop subexpr) { binop subexpr }
+ * where `binop' is any binary operator with a priority higher than `limit'
+ */
+static BinOpr subexpr(ktap_lexstate *ls, ktap_expdesc *v, int limit)
+{
+       BinOpr op;
+       UnOpr uop;
+
+       enterlevel(ls);
+       uop = getunopr(ls->t.token);
+       if (uop != OPR_NOUNOPR) {
+               int line = ls->linenumber;
+
+               lex_next(ls);
+               subexpr(ls, v, UNARY_PRIORITY);
+               codegen_prefix(ls->fs, uop, v, line);
+       } else
+               simpleexp(ls, v);
+
+       /* expand while operators have priorities higher than `limit' */
+       op = getbinopr(ls->t.token);
+       while (op != OPR_NOBINOPR && priority[op].left > limit) {
+               ktap_expdesc v2;
+               BinOpr nextop;
+               int line = ls->linenumber;
+
+               lex_next(ls);
+               codegen_infix(ls->fs, op, v);
+               /* read sub-expression with higher priority */
+               nextop = subexpr(ls, &v2, priority[op].right);
+               codegen_posfix(ls->fs, op, v, &v2, line);
+               op = nextop;
+       }
+       leavelevel(ls);
+       return op;  /* return first untreated operator */
+}
+
+static void expr(ktap_lexstate *ls, ktap_expdesc *v)
+{
+       subexpr(ls, v, 0);
+}
+
+/* }==================================================================== */
+
+/*
+ * {======================================================================
+ * Rules for Statements
+ * =======================================================================
+ */
+static void block(ktap_lexstate *ls)
+{
+       /* block -> statlist */
+       ktap_funcstate *fs = ls->fs;
+       ktap_blockcnt bl;
+
+       enterblock(fs, &bl, 0);
+       statlist(ls);
+       leaveblock(fs);
+}
+
+/*
+ * structure to chain all variables in the left-hand side of an
+ * assignment
+ */
+struct LHS_assign {
+       struct LHS_assign *prev;
+       ktap_expdesc v;  /* variable (global, local, upvalue, or indexed) */
+};
+
+/*
+ * check whether, in an assignment to an upvalue/local variable, the
+ * upvalue/local variable is begin used in a previous assignment to a
+ * table. If so, save original upvalue/local value in a safe place and
+ * use this safe copy in the previous assignment.
+ */
+static void check_conflict(ktap_lexstate *ls, struct LHS_assign *lh, ktap_expdesc *v)
+{
+       ktap_funcstate *fs = ls->fs;
+       int extra = fs->freereg;  /* eventual position to save local variable */
+       int conflict = 0;
+
+       for (; lh; lh = lh->prev) {  /* check all previous assignments */
+               if (lh->v.k == VINDEXED) {  /* assigning to a table? */
+                       /* table is the upvalue/local being assigned now? */
+                       if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
+                               conflict = 1;
+                               lh->v.u.ind.vt = VLOCAL;
+                               lh->v.u.ind.t = extra;  /* previous assignment will use safe copy */
+                       }
+                       /* index is the local being assigned? (index cannot be upvalue) */
+                       if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
+                               conflict = 1;
+                               lh->v.u.ind.idx = extra;  /* previous assignment will use safe copy */
+                       }
+               }
+       }
+       if (conflict) {
+               /* copy upvalue/local value to a temporary (in position 'extra') */
+               OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
+               codegen_codeABC(fs, op, extra, v->u.info, 0);
+               codegen_reserveregs(fs, 1);
+       }
+}
+
+static void assignment(ktap_lexstate *ls, struct LHS_assign *lh, int nvars)
+{
+       ktap_expdesc e;
+
+       check_condition(ls, vkisvar(lh->v.k), "syntax error");
+       if (testnext(ls, ',')) {  /* assignment -> ',' suffixedexp assignment */
+               struct LHS_assign nv;
+
+               nv.prev = lh;
+               suffixedexp(ls, &nv.v);
+               if (nv.v.k != VINDEXED)
+                       check_conflict(ls, lh, &nv.v);
+               checklimit(ls->fs, nvars + ls->nCcalls, KTAP_MAXCCALLS,
+                               "C levels");
+               assignment(ls, &nv, nvars+1);
+       } else if (testnext(ls, '=')) {  /* assignment -> '=' explist */
+               int nexps;
+
+               nexps = explist(ls, &e);
+               if (nexps != nvars) {
+                       adjust_assign(ls, nvars, nexps, &e);
+                       /* remove extra values */
+                       if (nexps > nvars)
+                               ls->fs->freereg -= nexps - nvars;
+               } else {
+                       /* close last expression */
+                       codegen_setoneret(ls->fs, &e);
+                       codegen_storevar(ls->fs, &lh->v, &e);
+                       return;  /* avoid default */
+               }
+       } else if (testnext(ls, TK_INCR)) { /* assignment -> '+=' explist */
+               int nexps;
+
+               nexps = explist(ls, &e);
+               if (nexps != nvars) {
+                       lex_syntaxerror(ls, "don't allow multi-assign for +=");
+               } else {
+                       /* close last expression */
+                       codegen_setoneret(ls->fs, &e);
+                       codegen_storeincr(ls->fs, &lh->v, &e);
+                       return;  /* avoid default */
+               }
+       }
+
+       init_exp(&e, VNONRELOC, ls->fs->freereg-1);  /* default assignment */
+       codegen_storevar(ls->fs, &lh->v, &e);
+}
+
+static int cond(ktap_lexstate *ls)
+{
+       /* cond -> exp */
+       ktap_expdesc v;
+       expr(ls, &v);  /* read condition */
+       if (v.k == VNIL)
+               v.k = VFALSE;  /* `falses' are all equal here */
+       codegen_goiftrue(ls->fs, &v);
+       return v.f;
+}
+
+static void gotostat(ktap_lexstate *ls, int pc)
+{
+       int line = ls->linenumber;
+       ktap_string *label;
+       int g;
+
+       if (testnext(ls, TK_GOTO))
+               label = str_checkname(ls);
+       else {
+               lex_next(ls);  /* skip break */
+               label = ktapc_ts_new("break");
+       }
+       g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);
+       findlabel(ls, g);  /* close it if label already defined */
+}
+
+/* check for repeated labels on the same block */
+static void checkrepeated(ktap_funcstate *fs, ktap_labellist *ll, ktap_string *label)
+{
+       int i;
+       for (i = fs->bl->firstlabel; i < ll->n; i++) {
+               if (ktapc_ts_eqstr(label, ll->arr[i].name)) {
+                       const char *msg = ktapc_sprintf(
+                               "label " KTAP_QS " already defined on line %d",
+                               getstr(label), ll->arr[i].line);
+                       semerror(fs->ls, msg);
+               }
+       }
+}
+
+/* skip no-op statements */
+static void skipnoopstat(ktap_lexstate *ls)
+{
+       while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
+               statement(ls);
+}
+
+static void labelstat (ktap_lexstate *ls, ktap_string *label, int line)
+{
+       /* label -> '::' NAME '::' */
+       ktap_funcstate *fs = ls->fs;
+       ktap_labellist *ll = &ls->dyd->label;
+       int l;  /* index of new label being created */
+
+       checkrepeated(fs, ll, label);  /* check for repeated labels */
+       checknext(ls, TK_DBCOLON);  /* skip double colon */
+       /* create new entry for this label */
+       l = newlabelentry(ls, ll, label, line, fs->pc);
+       skipnoopstat(ls);  /* skip other no-op statements */
+       if (block_follow(ls, 0)) {  /* label is last no-op statement in the block? */
+               /* assume that locals are already out of scope */
+               ll->arr[l].nactvar = fs->bl->nactvar;
+       }
+       findgotos(ls, &ll->arr[l]);
+}
+
+static void whilestat(ktap_lexstate *ls, int line)
+{
+       /* whilestat -> WHILE cond DO block END */
+       ktap_funcstate *fs = ls->fs;
+       int whileinit;
+       int condexit;
+       ktap_blockcnt bl;
+
+       lex_next(ls);  /* skip WHILE */
+       whileinit = codegen_getlabel(fs);
+       checknext(ls, '(');
+       condexit = cond(ls);
+       checknext(ls, ')');
+
+       enterblock(fs, &bl, 1);
+       //checknext(ls, TK_DO);
+       checknext(ls, '{');
+       block(ls);
+       codegen_jumpto(fs, whileinit);
+       checknext(ls, '}');
+       //check_match(ls, TK_END, TK_WHILE, line);
+       leaveblock(fs);
+       codegen_patchtohere(fs, condexit);  /* false conditions finish the loop */
+}
+
+static void repeatstat(ktap_lexstate *ls, int line)
+{
+       /* repeatstat -> REPEAT block UNTIL cond */
+       int condexit;
+       ktap_funcstate *fs = ls->fs;
+       int repeat_init = codegen_getlabel(fs);
+       ktap_blockcnt bl1, bl2;
+
+       enterblock(fs, &bl1, 1);  /* loop block */
+       enterblock(fs, &bl2, 0);  /* scope block */
+       lex_next(ls);  /* skip REPEAT */
+       statlist(ls);
+       check_match(ls, TK_UNTIL, TK_REPEAT, line);
+       condexit = cond(ls);  /* read condition (inside scope block) */
+       if (bl2.upval)  /* upvalues? */
+               codegen_patchclose(fs, condexit, bl2.nactvar);
+       leaveblock(fs);  /* finish scope */
+       codegen_patchlist(fs, condexit, repeat_init);  /* close the loop */
+       leaveblock(fs);  /* finish loop */
+}
+
+static int exp1(ktap_lexstate *ls)
+{
+       ktap_expdesc e;
+       int reg;
+
+       expr(ls, &e);
+       codegen_exp2nextreg(ls->fs, &e);
+       ktap_assert(e.k == VNONRELOC);
+       reg = e.u.info;
+       return reg;
+}
+
+static void forbody(ktap_lexstate *ls, int base, int line, int nvars, int isnum)
+{
+       /* forbody -> DO block */
+       ktap_blockcnt bl;
+       ktap_funcstate *fs = ls->fs;
+       int prep, endfor;
+
+       checknext(ls, ')');
+
+       adjustlocalvars(ls, 3);  /* control variables */
+       //checknext(ls, TK_DO);
+       checknext(ls, '{');
+       prep = isnum ? codegen_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : codegen_jump(fs);
+       enterblock(fs, &bl, 0);  /* scope for declared variables */
+       adjustlocalvars(ls, nvars);
+       codegen_reserveregs(fs, nvars);
+       block(ls);
+       leaveblock(fs);  /* end of scope for declared variables */
+       codegen_patchtohere(fs, prep);
+       if (isnum)  /* numeric for? */
+               endfor = codegen_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP);
+       else {  /* generic for */
+               codegen_codeABC(fs, OP_TFORCALL, base, 0, nvars);
+               codegen_fixline(fs, line);
+               endfor = codegen_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP);
+       }
+       codegen_patchlist(fs, endfor, prep + 1);
+       codegen_fixline(fs, line);
+}
+
+static void fornum(ktap_lexstate *ls, ktap_string *varname, int line)
+{
+       /* fornum -> NAME = exp1,exp1[,exp1] forbody */
+       ktap_funcstate *fs = ls->fs;
+       int base = fs->freereg;
+
+       new_localvarliteral(ls, "(for index)");
+       new_localvarliteral(ls, "(for limit)");
+       new_localvarliteral(ls, "(for step)");
+       new_localvar(ls, varname);
+       checknext(ls, '=');
+       exp1(ls);  /* initial value */
+       checknext(ls, ',');
+       exp1(ls);  /* limit */
+       if (testnext(ls, ','))
+               exp1(ls);  /* optional step */
+       else {  /* default step = 1 */
+               codegen_codek(fs, fs->freereg, codegen_numberK(fs, 1));
+               codegen_reserveregs(fs, 1);
+       }
+       forbody(ls, base, line, 1, 1);
+}
+
+static void forlist(ktap_lexstate *ls, ktap_string *indexname)
+{
+       /* forlist -> NAME {,NAME} IN explist forbody */
+       ktap_funcstate *fs = ls->fs;
+       ktap_expdesc e;
+       int nvars = 4;  /* gen, state, control, plus at least one declared var */
+       int line;
+       int base = fs->freereg;
+
+       /* create control variables */
+       new_localvarliteral(ls, "(for generator)");
+       new_localvarliteral(ls, "(for state)");
+       new_localvarliteral(ls, "(for control)");
+       /* create declared variables */
+       new_localvar(ls, indexname);
+       while (testnext(ls, ',')) {
+               new_localvar(ls, str_checkname(ls));
+               nvars++;
+       }
+       checknext(ls, TK_IN);
+       line = ls->linenumber;
+       adjust_assign(ls, 3, explist(ls, &e), &e);
+       codegen_checkstack(fs, 3);  /* extra space to call generator */
+       forbody(ls, base, line, nvars - 3, 0);
+}
+
+static void forstat(ktap_lexstate *ls, int line)
+{
+       /* forstat -> FOR (fornum | forlist) END */
+       ktap_funcstate *fs = ls->fs;
+       ktap_string *varname;
+       ktap_blockcnt bl;
+
+       enterblock(fs, &bl, 1);  /* scope for loop and control variables */
+       lex_next(ls);  /* skip `for' */
+
+       checknext(ls, '(');
+       varname = str_checkname(ls);  /* first variable name */
+       switch (ls->t.token) {
+       case '=':
+               fornum(ls, varname, line);
+               break;
+       case ',': case TK_IN:
+               forlist(ls, varname);
+               break;
+       default: 
+               lex_syntaxerror(ls, KTAP_QL("=") " or " KTAP_QL("in") " expected");
+       }
+       //check_match(ls, TK_END, TK_FOR, line);
+       checknext(ls, '}');
+       leaveblock(fs);  /* loop scope (`break' jumps to this point) */
+}
+
+static void test_then_block(ktap_lexstate *ls, int *escapelist)
+{
+       /* test_then_block -> [IF | ELSEIF] cond THEN block */
+       ktap_blockcnt bl;
+       ktap_funcstate *fs = ls->fs;
+       ktap_expdesc v;
+       int jf;  /* instruction to skip 'then' code (if condition is false) */
+
+       lex_next(ls);  /* skip IF or ELSEIF */
+       checknext(ls, '(');
+       expr(ls, &v);  /* read condition */
+       checknext(ls, ')');
+       //checknext(ls, TK_THEN);
+       checknext(ls, '{');
+       if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
+               codegen_goiffalse(ls->fs, &v);  /* will jump to label if condition is true */
+               enterblock(fs, &bl, 0);  /* must enter block before 'goto' */
+               gotostat(ls, v.t);  /* handle goto/break */
+               skipnoopstat(ls);  /* skip other no-op statements */
+               if (block_follow(ls, 0)) {  /* 'goto' is the entire block? */
+                       leaveblock(fs);
+                       checknext(ls, '}');
+                       return;  /* and that is it */
+               } else  /* must skip over 'then' part if condition is false */
+                       jf = codegen_jump(fs);
+       } else {  /* regular case (not goto/break) */
+               codegen_goiftrue(ls->fs, &v);  /* skip over block if condition is false */
+               enterblock(fs, &bl, 0);
+               jf = v.f;
+       }
+       statlist(ls);  /* `then' part */
+       checknext(ls, '}');
+       leaveblock(fs);
+       if (ls->t.token == TK_ELSE || ls->t.token == TK_ELSEIF)  /* followed by 'else'/'elseif'? */
+               codegen_concat(fs, escapelist, codegen_jump(fs));  /* must jump over it */
+       codegen_patchtohere(fs, jf);
+}
+
+static void ifstat(ktap_lexstate *ls, int line)
+{
+       /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
+       ktap_funcstate *fs = ls->fs;
+       int escapelist = NO_JUMP;  /* exit list for finished parts */
+
+       test_then_block(ls, &escapelist);  /* IF cond THEN block */
+       while (ls->t.token == TK_ELSEIF)
+               test_then_block(ls, &escapelist);  /* ELSEIF cond THEN block */
+       if (testnext(ls, TK_ELSE)) {
+               checknext(ls, '{');
+               block(ls);  /* `else' part */
+               checknext(ls, '}');
+       }
+       //check_match(ls, TK_END, TK_IF, line);
+       codegen_patchtohere(fs, escapelist);  /* patch escape list to 'if' end */
+}
+
+static void localfunc(ktap_lexstate *ls)
+{
+       ktap_expdesc b;
+       ktap_funcstate *fs = ls->fs;
+
+       new_localvar(ls, str_checkname(ls));  /* new local variable */
+       adjustlocalvars(ls, 1);  /* enter its scope */
+       body(ls, &b, 0, ls->linenumber);  /* function created in next register */
+       /* debug information will only see the variable after this point! */
+       getlocvar(fs, b.u.info)->startpc = fs->pc;
+}
+
+static void localstat(ktap_lexstate *ls)
+{
+       /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */
+       int nvars = 0;
+       int nexps;
+       ktap_expdesc e;
+
+       do {
+               new_localvar(ls, str_checkname(ls));
+               nvars++;
+       } while (testnext(ls, ','));
+       if (testnext(ls, '='))
+               nexps = explist(ls, &e);
+       else {
+               e.k = VVOID;
+               nexps = 0;
+       }
+       adjust_assign(ls, nvars, nexps, &e);
+       adjustlocalvars(ls, nvars);
+}
+
+static int funcname(ktap_lexstate *ls, ktap_expdesc *v)
+{
+       /* funcname -> NAME {fieldsel} [`:' NAME] */
+       int ismethod = 0;
+
+       singlevar(ls, v);
+       while (ls->t.token == '.')
+               fieldsel(ls, v);
+               if (ls->t.token == ':') {
+                       ismethod = 1;
+                       fieldsel(ls, v);
+       }
+       return ismethod;
+}
+
+static void funcstat(ktap_lexstate *ls, int line)
+{
+       /* funcstat -> FUNCTION funcname body */
+       int ismethod;
+       ktap_expdesc v, b;
+
+       lex_next(ls);  /* skip FUNCTION */
+       ismethod = funcname(ls, &v);
+       body(ls, &b, ismethod, line);
+       codegen_storevar(ls->fs, &v, &b);
+       codegen_fixline(ls->fs, line);  /* definition `happens' in the first line */
+}
+
+static void exprstat(ktap_lexstate *ls)
+{
+       /* stat -> func | assignment */
+       ktap_funcstate *fs = ls->fs;
+       struct LHS_assign v;
+
+       suffixedexp(ls, &v.v);
+       /* stat -> assignment ? */
+       if (ls->t.token == '=' || ls->t.token == ',' ||
+           ls->t.token == TK_INCR) {
+               v.prev = NULL;
+               assignment(ls, &v, 1);
+       } else {  /* stat -> func */
+               check_condition(ls, v.v.k == VCALL, "syntax error");
+               SETARG_C(getcode(fs, &v.v), 1);  /* call statement uses no results */
+       }
+}
+
+static void retstat(ktap_lexstate *ls)
+{
+       /* stat -> RETURN [explist] [';'] */
+       ktap_funcstate *fs = ls->fs;
+       ktap_expdesc e;
+       int first, nret;  /* registers with returned values */
+
+       if (block_follow(ls, 1) || ls->t.token == ';')
+               first = nret = 0;  /* return no values */
+       else {
+               nret = explist(ls, &e);  /* optional return values */
+               if (hasmultret(e.k)) {
+                       codegen_setmultret(fs, &e);
+                       if (e.k == VCALL && nret == 1) {  /* tail call? */
+                               SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
+                               ktap_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
+                       }
+                       first = fs->nactvar;
+                       nret = KTAP_MULTRET;  /* return all values */
+               } else {
+                       if (nret == 1)  /* only one single value? */
+                               first = codegen_exp2anyreg(fs, &e);
+                       else {
+                               codegen_exp2nextreg(fs, &e);  /* values must go to the `stack' */
+                               first = fs->nactvar;  /* return all `active' values */
+                               ktap_assert(nret == fs->freereg - first);
+                       }
+               }
+       }
+       codegen_ret(fs, first, nret);
+       testnext(ls, ';');  /* skip optional semicolon */
+}
+
+static void tracestat(ktap_lexstate *ls)
+{
+       ktap_expdesc v0, key, args;
+       ktap_expdesc *v = &v0;
+       ktap_string *kdebug_str = ktapc_ts_new("kdebug");
+       ktap_string *probe_str = ktapc_ts_new("probe_by_id");
+       ktap_string *probe_end_str = ktapc_ts_new("probe_end");
+       ktap_funcstate *fs = ls->fs;
+       int token = ls->t.token;
+       int line = ls->linenumber;
+       int base, nparams;
+
+       if (token == TK_TRACE)
+               lex_read_string_until(ls, '{');
+       else
+               lex_next(ls);  /* skip "trace_end" keyword */
+
+       /* kdebug */
+       singlevaraux(fs, ls->envn, v, 1);  /* get environment variable */
+       codestring(ls, &key, kdebug_str);  /* key is variable name */
+       codegen_indexed(fs, v, &key);  /* env[varname] */
+
+       /* fieldsel: kdebug.probe */
+       codegen_exp2anyregup(fs, v);
+       if (token == TK_TRACE)
+               codestring(ls, &key, probe_str);
+       else if (token == TK_TRACE_END)
+               codestring(ls, &key, probe_end_str);
+       codegen_indexed(fs, v, &key);
+
+       /* funcargs*/
+       codegen_exp2nextreg(fs, v);
+
+       if (token == TK_TRACE) {
+               /* argument: EVENTDEF string */
+               check(ls, TK_STRING);
+               enterlevel(ls);
+               ktap_string *ts = ktapc_parse_eventdef(ls->t.seminfo.ts);
+               check_condition(ls, ts != NULL, "Cannot parse eventdef");
+               codestring(ls, &args, ts);
+               lex_next(ls);  /* skip EVENTDEF string */
+               leavelevel(ls);
+
+               codegen_exp2nextreg(fs, &args); /* for next argument */
+       }
+
+       /* argument: callback function */
+       enterlevel(ls);
+       func_body_no_args(ls, &args, ls->linenumber);
+       leavelevel(ls);
+
+       codegen_setmultret(fs, &args);
+
+       base = v->u.info;  /* base register for call */
+       if (hasmultret(args.k))
+               nparams = KTAP_MULTRET;  /* open call */
+       else {
+               codegen_exp2nextreg(fs, &args);  /* close last argument */
+               nparams = fs->freereg - (base+1);
+       }
+       init_exp(v, VCALL, codegen_codeABC(fs, OP_CALL, base, nparams+1, 2));
+       codegen_fixline(fs, line);
+       fs->freereg = base+1;
+
+       check_condition(ls, v->k == VCALL, "syntax error");
+       SETARG_C(getcode(fs, v), 1);  /* call statement uses no results */
+}
+
+static void timerstat(ktap_lexstate *ls)
+{
+       ktap_expdesc v0, key, args;
+       ktap_expdesc *v = &v0;
+       ktap_funcstate *fs = ls->fs;
+       ktap_string *token_str = ls->t.seminfo.ts;
+       ktap_string *interval_str;
+       int line = ls->linenumber;
+       int base, nparams;
+
+       lex_next(ls);  /* skip profile/tick keyword */
+       check(ls, '-');
+
+       lex_read_string_until(ls, '{');
+       interval_str = ls->t.seminfo.ts;
+
+       //printf("timerstat str: %s\n", getstr(interval_str));
+       //exit(0);
+
+       /* timer */
+       singlevaraux(fs, ls->envn, v, 1);  /* get environment variable */
+       codestring(ls, &key, ktapc_ts_new("timer"));  /* key is variable name */
+       codegen_indexed(fs, v, &key);  /* env[varname] */
+
+       /* fieldsel: timer.profile, timer.tick */
+       codegen_exp2anyregup(fs, v);
+       codestring(ls, &key, token_str);
+       codegen_indexed(fs, v, &key);
+
+       /* funcargs*/
+       codegen_exp2nextreg(fs, v);
+
+       /* argument: interval string */
+       check(ls, TK_STRING);
+       enterlevel(ls);
+       codestring(ls, &args, interval_str);
+       lex_next(ls);  /* skip interval string */
+       leavelevel(ls);
+
+       codegen_exp2nextreg(fs, &args); /* for next argument */
+
+       /* argument: callback function */
+       enterlevel(ls);
+       func_body_no_args(ls, &args, ls->linenumber);
+       leavelevel(ls);
+
+       codegen_setmultret(fs, &args);
+
+       base = v->u.info;  /* base register for call */
+       if (hasmultret(args.k))
+               nparams = KTAP_MULTRET;  /* open call */
+       else {
+               codegen_exp2nextreg(fs, &args);  /* close last argument */
+               nparams = fs->freereg - (base+1);
+       }
+       init_exp(v, VCALL, codegen_codeABC(fs, OP_CALL, base, nparams+1, 2));
+       codegen_fixline(fs, line);
+       fs->freereg = base+1;
+
+       check_condition(ls, v->k == VCALL, "syntax error");
+       SETARG_C(getcode(fs, v), 1);  /* call statement uses no results */
+}
+
+static void statement(ktap_lexstate *ls)
+{
+       int line = ls->linenumber;  /* may be needed for error messages */
+
+       enterlevel(ls);
+       switch (ls->t.token) {
+       case ';': {  /* stat -> ';' (empty statement) */
+               lex_next(ls);  /* skip ';' */
+               break;
+       }
+       case TK_IF: {  /* stat -> ifstat */
+               ifstat(ls, line);
+               break;
+       }
+       case TK_WHILE: {  /* stat -> whilestat */
+               whilestat(ls, line);
+               break;
+       }
+       case TK_DO: {  /* stat -> DO block END */
+               lex_next(ls);  /* skip DO */
+               block(ls);
+               check_match(ls, TK_END, TK_DO, line);
+               break;
+       }
+       case TK_FOR: {  /* stat -> forstat */
+               forstat(ls, line);
+               break;
+       }
+       case TK_REPEAT: {  /* stat -> repeatstat */
+               repeatstat(ls, line);
+               break;
+       }
+       case TK_FUNCTION: {  /* stat -> funcstat */
+               funcstat(ls, line);
+               break;
+       }
+       case TK_LOCAL: {  /* stat -> localstat */
+               lex_next(ls);  /* skip LOCAL */
+               if (testnext(ls, TK_FUNCTION))  /* local function? */
+                       localfunc(ls);
+               else
+                       localstat(ls);
+               break;
+       }
+       case TK_DBCOLON: {  /* stat -> label */
+               lex_next(ls);  /* skip double colon */
+               labelstat(ls, str_checkname(ls), line);
+               break;
+       }
+       case TK_RETURN: {  /* stat -> retstat */
+               lex_next(ls);  /* skip RETURN */
+               retstat(ls);
+               break;
+       }
+       case TK_BREAK:   /* stat -> breakstat */
+       case TK_GOTO: {  /* stat -> 'goto' NAME */
+               gotostat(ls, codegen_jump(ls->fs));
+               break;
+       }
+
+       case TK_TRACE:
+       case TK_TRACE_END:
+               tracestat(ls);
+               break;
+       case TK_PROFILE:
+       case TK_TICK:
+               timerstat(ls);
+               break;
+       default: {  /* stat -> func | assignment */
+               exprstat(ls);
+               break;
+       }
+       }
+       //ktap_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
+       //      ls->fs->freereg >= ls->fs->nactvar);
+       ls->fs->freereg = ls->fs->nactvar;  /* free registers */
+       leavelevel(ls);
+}
+/* }====================================================================== */
+
+/*
+ * compiles the main function, which is a regular vararg function with an upvalue
+ */
+static void mainfunc(ktap_lexstate *ls, ktap_funcstate *fs)
+{
+       ktap_blockcnt bl;
+       ktap_expdesc v;
+
+       open_func(ls, fs, &bl);
+       fs->f->is_vararg = 1;  /* main function is always vararg */
+       init_exp(&v, VLOCAL, 0);  /* create and... */
+       newupvalue(fs, ls->envn, &v);  /* ...set environment upvalue */
+       lex_next(ls);  /* read first token */
+       statlist(ls);  /* parse main body */
+       check(ls, TK_EOS);
+       close_func(ls);
+}
+
+ktap_closure *ktapc_parser(char *ptr, const char *name)
+{
+       ktap_lexstate lexstate;
+       ktap_funcstate funcstate;
+       ktap_dyndata dyd;
+       ktap_mbuffer buff;
+       int firstchar = *ptr++;
+       ktap_closure *cl = ktapc_newlclosure(1);  /* create main closure */
+
+       memset(&lexstate, 0, sizeof(ktap_lexstate));
+       memset(&funcstate, 0, sizeof(ktap_funcstate));
+       funcstate.f = cl->l.p = ktapc_newproto();
+       funcstate.f->source = ktapc_ts_new(name);  /* create and anchor ktap_string */
+
+       lex_init();
+
+       mbuff_init(&buff);
+       memset(&dyd, 0, sizeof(ktap_dyndata));
+       lexstate.buff = &buff;
+       lexstate.dyd = &dyd;
+       lex_setinput(&lexstate, ptr, funcstate.f->source, firstchar);
+
+       mainfunc(&lexstate, &funcstate);
+
+       ktap_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
+
+       /* all scopes should be correctly finished */
+       ktap_assert(dyd.actvar.n == 0 && dyd.gt.n == 0 && dyd.label.n == 0);
+       return cl;
+}
+
diff --git a/drivers/staging/ktap/userspace/util.c b/drivers/staging/ktap/userspace/util.c
new file mode 100644 (file)
index 0000000..8124de9
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * util.c
+ *
+ * This file is part of ktap by Jovi Zhangwei.
+ *
+ * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
+ *
+ * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
+ *  - The part of code in this file is copied from lua initially.
+ *  - lua's MIT license is compatible with GPL.
+ *
+ * ktap is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * ktap is distributed in the hope 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.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "../include/ktap_types.h"
+#include "ktapc.h"
+
+/*
+ * converts an integer to a "floating point byte", represented as
+ * (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
+ * eeeee != 0 and (xxx) otherwise.
+ */
+int ktapc_int2fb(unsigned int x)
+{
+       int e = 0;  /* exponent */
+
+       if (x < 8)
+               return x;
+       while (x >= 0x10) {
+               x = (x+1) >> 1;
+               e++;
+       }
+       return ((e+1) << 3) | ((int)x - 8);
+}
+
+/* converts back */
+int ktapc_fb2int(int x)
+{
+       int e = (x >> 3) & 0x1f;
+
+       if (e == 0)
+               return x;
+       else
+               return ((x & 7) + 8) << (e - 1);
+}
+
+int ktapc_ceillog2(unsigned int x)
+{
+       static const u8 log_2[256] = {
+       0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+       6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+       8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+       8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+       8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+       8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+       };
+       int l = 0;
+
+       x--;
+       while (x >= 256) {
+               l += 8;
+               x >>= 8;
+       }
+       return l + log_2[x];
+}
+
+ktap_number ktapc_arith(int op, ktap_number v1, ktap_number v2)
+{
+       switch (op) {
+       case KTAP_OPADD: return NUMADD(v1, v2);
+       case KTAP_OPSUB: return NUMSUB(v1, v2);
+       case KTAP_OPMUL: return NUMMUL(v1, v2);
+       case KTAP_OPDIV: return NUMDIV(v1, v2);
+       case KTAP_OPMOD: return NUMMOD(v1, v2);
+       //case KTAP_OPPOW: return NUMPOW(v1, v2);
+       case KTAP_OPUNM: return NUMUNM(v1);
+       default: ktap_assert(0); return 0;
+       }
+}
+
+int ktapc_hexavalue(int c)
+{
+       if (isdigit(c))
+               return c - '0';
+       else
+               return tolower(c) - 'a' + 10;
+}
+
+static int isneg(const char **s)
+{
+       if (**s == '-') {
+               (*s)++;
+               return 1;
+       } else if (**s == '+')
+               (*s)++;
+
+       return 0;
+}
+
+static ktap_number readhexa(const char **s, ktap_number r, int *count)
+{
+       for (; isxdigit((unsigned char)(**s)); (*s)++) {  /* read integer part */
+               r = (r * 16.0) + (ktap_number)(ktapc_hexavalue((unsigned char)(**s)));
+               (*count)++;
+       }
+
+       return r;
+}
+
+/*
+ * convert an hexadecimal numeric string to a number, following
+ * C99 specification for 'strtod'
+ */
+static ktap_number strx2number(const char *s, char **endptr)
+{
+       ktap_number r = 0.0;
+       int e = 0, i = 0;
+       int neg = 0;  /* 1 if number is negative */
+
+       *endptr = (char *)s;  /* nothing is valid yet */
+       while (isspace((unsigned char)(*s)))
+               s++;  /* skip initial spaces */
+
+       neg = isneg(&s);  /* check signal */
+       if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')))  /* check '0x' */
+               return 0.0;  /* invalid format (no '0x') */
+
+       s += 2;  /* skip '0x' */
+       r = readhexa(&s, r, &i);  /* read integer part */
+       if (*s == '.') {
+               s++;  /* skip dot */
+               r = readhexa(&s, r, &e);  /* read fractional part */
+       }
+
+       if (i == 0 && e == 0)
+               return 0.0;  /* invalid format (no digit) */
+       e *= -4;  /* each fractional digit divides value by 2^-4 */
+       *endptr = (char *)s;  /* valid up to here */
+
+       if (*s == 'p' || *s == 'P') {  /* exponent part? */
+               int exp1 = 0;
+               int neg1;
+
+               s++;  /* skip 'p' */
+               neg1 = isneg(&s);  /* signal */
+               if (!isdigit((unsigned char)(*s)))
+                       goto ret;  /* must have at least one digit */
+               while (isdigit((unsigned char)(*s)))  /* read exponent */
+                       exp1 = exp1 * 10 + *(s++) - '0';
+               if (neg1) exp1 = -exp1;
+                       e += exp1;
+       }
+
+       *endptr = (char *)s;  /* valid up to here */
+ ret:
+       if (neg)
+               r = -r;
+
+       return ldexp(r, e);
+}
+
+int ktapc_str2d(const char *s, size_t len, ktap_number *result)
+{
+       char *endptr;
+
+       if (strpbrk(s, "nN"))  /* reject 'inf' and 'nan' */
+               return 0;
+       else if (strpbrk(s, "xX"))  /* hexa? */
+               *result = strx2number(s, &endptr);
+       else
+               *result = strtod(s, &endptr);
+
+       if (endptr == s)
+               return 0;  /* nothing recognized */
+       while (isspace((unsigned char)(*endptr)))
+               endptr++;
+       return (endptr == s + len);  /* OK if no trailing characters */
+}
+
+/* number of chars of a literal string without the ending \0 */
+#define LL(x)  (sizeof(x)/sizeof(char) - 1)
+
+#define RETS   "..."
+#define PRE    "[string \""
+#define POS    "\"]"
+
+#define addstr(a,b,l)  ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
+
+void ktapc_chunkid(char *out, const char *source, size_t bufflen)
+{
+       size_t l = strlen(source);
+
+       if (*source == '=') {  /* 'literal' source */
+               if (l <= bufflen)  /* small enough? */
+                       memcpy(out, source + 1, l * sizeof(char));
+               else {  /* truncate it */
+                       addstr(out, source + 1, bufflen - 1);
+                       *out = '\0';
+               }
+       } else if (*source == '@') {  /* file name */
+               if (l <= bufflen)  /* small enough? */
+                       memcpy(out, source + 1, l * sizeof(char));
+               else {  /* add '...' before rest of name */
+                       addstr(out, RETS, LL(RETS));
+                       bufflen -= LL(RETS);
+                       memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
+               }
+       } else {  /* string; format as [string "source"] */
+               const char *nl = strchr(source, '\n');  /* find first new line (if any) */
+               addstr(out, PRE, LL(PRE));  /* add prefix */
+               bufflen -= LL(PRE RETS POS) + 1;  /* save space for prefix+suffix+'\0' */
+               if (l < bufflen && nl == NULL) {  /* small one-line source? */
+                       addstr(out, source, l);  /* keep it */
+               } else {
+                       if (nl != NULL)
+                               l = nl - source;  /* stop at first newline */
+                       if (l > bufflen)
+                               l = bufflen;
+                       addstr(out, source, l);
+                       addstr(out, RETS, LL(RETS));
+               }
+               memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
+       }
+}
+
+
+/*
+ * strglobmatch is copyed from perf(linux/tools/perf/util/string.c)
+ */
+
+/* Character class matching */
+static bool __match_charclass(const char *pat, char c, const char **npat)
+{
+       bool complement = false, ret = true;
+
+       if (*pat == '!') {
+               complement = true;
+               pat++;
+       }
+       if (*pat++ == c)        /* First character is special */
+               goto end;
+
+       while (*pat && *pat != ']') {   /* Matching */
+               if (*pat == '-' && *(pat + 1) != ']') { /* Range */
+                       if (*(pat - 1) <= c && c <= *(pat + 1))
+                               goto end;
+                       if (*(pat - 1) > *(pat + 1))
+                               goto error;
+                       pat += 2;
+               } else if (*pat++ == c)
+                       goto end;
+       }
+       if (!*pat)
+               goto error;
+       ret = false;
+
+end:
+       while (*pat && *pat != ']')     /* Searching closing */
+               pat++;
+       if (!*pat)
+               goto error;
+       *npat = pat + 1;
+       return complement ? !ret : ret;
+
+error:
+       return false;
+}
+
+/* Glob/lazy pattern matching */
+static bool __match_glob(const char *str, const char *pat, bool ignore_space)
+{
+       while (*str && *pat && *pat != '*') {
+               if (ignore_space) {
+                       /* Ignore spaces for lazy matching */
+                       if (isspace(*str)) {
+                               str++;
+                               continue;
+                       }
+                       if (isspace(*pat)) {
+                               pat++;
+                               continue;
+                       }
+               }
+               if (*pat == '?') {      /* Matches any single character */
+                       str++;
+                       pat++;
+                       continue;
+               } else if (*pat == '[') /* Character classes/Ranges */
+                       if (__match_charclass(pat + 1, *str, &pat)) {
+                               str++;
+                               continue;
+                       } else
+                               return false;
+               else if (*pat == '\\') /* Escaped char match as normal char */
+                       pat++;
+               if (*str++ != *pat++)
+                       return false;
+       }
+       /* Check wild card */
+       if (*pat == '*') {
+               while (*pat == '*')
+                       pat++;
+               if (!*pat)      /* Tail wild card matches all */
+                       return true;
+               while (*str)
+                       if (__match_glob(str++, pat, ignore_space))
+                               return true;
+       }
+       return !*str && !*pat;
+}
+
+/**
+ * strglobmatch - glob expression pattern matching
+ * @str: the target string to match
+ * @pat: the pattern string to match
+ *
+ * This returns true if the @str matches @pat. @pat can includes wildcards
+ * ('*','?') and character classes ([CHARS], complementation and ranges are
+ * also supported). Also, this supports escape character ('\') to use special
+ * characters as normal character.
+ *
+ * Note: if @pat syntax is broken, this always returns false.
+ */
+bool strglobmatch(const char *str, const char *pat)
+{
+       return __match_glob(str, pat, false);
+}
+
index 471c10c116ec823d54587c5426d79881cfc0db46..ee1799056b482aa33cf7fc01418fa3897fdb3a1f 100644 (file)
@@ -205,7 +205,7 @@ static int line6_send_raw_message_async_part(struct message *msg,
                        __func__, retval);
                usb_free_urb(urb);
                kfree(msg);
-               return -EINVAL;
+               return retval;
        }
 
        return 0;
index e3f9a53dbd96604ee5c6ab6e9eccd06511a96be7..3f6d78c585fb925d75bb630e07dab6f67c124b95 100644 (file)
@@ -144,7 +144,7 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
        if (retval < 0) {
                dev_err(line6->ifcdev, "usb_submit_urb failed\n");
                usb_free_urb(urb);
-               return -EINVAL;
+               return retval;
        }
 
        ++line6->line6midi->num_active_send_urbs;
@@ -205,7 +205,7 @@ static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,
        if (up)
                line6->line6midi->substream_receive = substream;
        else
-               line6->line6midi->substream_receive = 0;
+               line6->line6midi->substream_receive = NULL;
 }
 
 static struct snd_rawmidi_ops line6_midi_output_ops = {
index f3d4a896a75a1045282f6fa951e93eaa01bcee8e..8b137891791fe96927ad78e64b0aad7bded08bdc 100644 (file)
@@ -1,111 +1 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * 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 version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- * GPL HEADER END
- */
-/*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
- * Use is subject to license terms.
- *
- * Copyright (c) 2012, Intel Corporation.
- */
-/*
- * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
- */
-#ifndef _LIBCFS_BITMAP_H_
-#define _LIBCFS_BITMAP_H_
 
-
-typedef struct {
-       int          size;
-       unsigned long   data[0];
-} cfs_bitmap_t;
-
-#define CFS_BITMAP_SIZE(nbits) \
-     (((nbits/BITS_PER_LONG)+1)*sizeof(long)+sizeof(cfs_bitmap_t))
-
-static inline
-cfs_bitmap_t *CFS_ALLOCATE_BITMAP(int size)
-{
-       cfs_bitmap_t *ptr;
-
-       OBD_ALLOC(ptr, CFS_BITMAP_SIZE(size));
-       if (ptr == NULL)
-               return ptr;
-
-       ptr->size = size;
-
-       return ptr;
-}
-
-#define CFS_FREE_BITMAP(ptr)   OBD_FREE(ptr, CFS_BITMAP_SIZE(ptr->size))
-
-static inline
-void cfs_bitmap_set(cfs_bitmap_t *bitmap, int nbit)
-{
-       set_bit(nbit, bitmap->data);
-}
-
-static inline
-void cfs_bitmap_clear(cfs_bitmap_t *bitmap, int nbit)
-{
-       test_and_clear_bit(nbit, bitmap->data);
-}
-
-static inline
-int cfs_bitmap_check(cfs_bitmap_t *bitmap, int nbit)
-{
-       return test_bit(nbit, bitmap->data);
-}
-
-static inline
-int cfs_bitmap_test_and_clear(cfs_bitmap_t *bitmap, int nbit)
-{
-       return test_and_clear_bit(nbit, bitmap->data);
-}
-
-/* return 0 is bitmap has none set bits */
-static inline
-int cfs_bitmap_check_empty(cfs_bitmap_t *bitmap)
-{
-       return find_first_bit(bitmap->data, bitmap->size) == bitmap->size;
-}
-
-static inline
-void cfs_bitmap_copy(cfs_bitmap_t *new, cfs_bitmap_t *old)
-{
-       int newsize;
-
-       LASSERT(new->size >= old->size);
-       newsize = new->size;
-       memcpy(new, old, CFS_BITMAP_SIZE(old->size));
-       new->size = newsize;
-}
-
-#define cfs_foreach_bit(bitmap, pos)                                   \
-       for ((pos) = find_first_bit((bitmap)->data, bitmap->size);      \
-            (pos) < (bitmap)->size;                                    \
-            (pos) = find_next_bit((bitmap)->data, (bitmap)->size, (pos) + 1))
-
-#endif
index 98f5be243c8ece7af42641ef8d08a1761c1c6e26..b06505d8620d7de0becca75fb2604e59c46d01f4 100644 (file)
@@ -81,10 +81,10 @@ struct cfs_hash_ops;
 struct cfs_hash_lock_ops;
 struct cfs_hash_hlist_ops;
 
-typedef union {
+union cfs_hash_lock {
        rwlock_t                rw;             /**< rwlock */
        spinlock_t              spin;           /**< spinlock */
-} cfs_hash_lock_t;
+};
 
 /**
  * cfs_hash_bucket is a container of:
@@ -98,7 +98,7 @@ typedef union {
  * - some extra bytes (caller can require it while creating hash)
  */
 typedef struct cfs_hash_bucket {
-       cfs_hash_lock_t         hsb_lock;       /**< bucket lock */
+       union cfs_hash_lock     hsb_lock;       /**< bucket lock */
        __u32                   hsb_count;      /**< current entries */
        __u32                   hsb_version;    /**< change version */
        unsigned int            hsb_index;      /**< index of bucket */
@@ -213,7 +213,7 @@ enum cfs_hash_tag {
 typedef struct cfs_hash {
        /** serialize with rehash, or serialize all operations if
         * the hash-table has CFS_HASH_NO_BKTLOCK */
-       cfs_hash_lock_t      hs_lock;
+       union cfs_hash_lock          hs_lock;
        /** hash operations */
        struct cfs_hash_ops     *hs_ops;
        /** hash lock operations */
@@ -276,13 +276,13 @@ typedef struct cfs_hash {
 
 typedef struct cfs_hash_lock_ops {
        /** lock the hash table */
-       void    (*hs_lock)(cfs_hash_lock_t *lock, int exclusive);
+       void    (*hs_lock)(union cfs_hash_lock *lock, int exclusive);
        /** unlock the hash table */
-       void    (*hs_unlock)(cfs_hash_lock_t *lock, int exclusive);
+       void    (*hs_unlock)(union cfs_hash_lock *lock, int exclusive);
        /** lock the hash bucket */
-       void    (*hs_bkt_lock)(cfs_hash_lock_t *lock, int exclusive);
+       void    (*hs_bkt_lock)(union cfs_hash_lock *lock, int exclusive);
        /** unlock the hash bucket */
-       void    (*hs_bkt_unlock)(cfs_hash_lock_t *lock, int exclusive);
+       void    (*hs_bkt_unlock)(union cfs_hash_lock *lock, int exclusive);
 } cfs_hash_lock_ops_t;
 
 typedef struct cfs_hash_hlist_ops {
index 49b0f1287a69ca85172b590bcec15d56144cd453..b6f8ad38628baec5cce918aca15e7462872680b3 100644 (file)
@@ -47,14 +47,14 @@ CFS_MODULE_PARM(local_nid_dist_zero, "i", int, 0444,
                "Reserved");
 
 int
-lnet_fail_nid (lnet_nid_t nid, unsigned int threshold)
+lnet_fail_nid(lnet_nid_t nid, unsigned int threshold)
 {
        lnet_test_peer_t  *tp;
        struct list_head        *el;
        struct list_head        *next;
        struct list_head         cull;
 
-       LASSERT (the_lnet.ln_init);
+       LASSERT(the_lnet.ln_init);
 
        /* NB: use lnet_net_lock(0) to serialize operations on test peers */
        if (threshold != 0) {
@@ -77,31 +77,30 @@ lnet_fail_nid (lnet_nid_t nid, unsigned int threshold)
 
        lnet_net_lock(0);
 
-       list_for_each_safe (el, next, &the_lnet.ln_test_peers) {
-               tp = list_entry (el, lnet_test_peer_t, tp_list);
+       list_for_each_safe(el, next, &the_lnet.ln_test_peers) {
+               tp = list_entry(el, lnet_test_peer_t, tp_list);
 
                if (tp->tp_threshold == 0 ||    /* needs culling anyway */
                    nid == LNET_NID_ANY ||       /* removing all entries */
-                   tp->tp_nid == nid)    /* matched this one */
-               {
-                       list_del (&tp->tp_list);
-                       list_add (&tp->tp_list, &cull);
+                   tp->tp_nid == nid) {          /* matched this one */
+                       list_del(&tp->tp_list);
+                       list_add(&tp->tp_list, &cull);
                }
        }
 
        lnet_net_unlock(0);
 
-       while (!list_empty (&cull)) {
-               tp = list_entry (cull.next, lnet_test_peer_t, tp_list);
+       while (!list_empty(&cull)) {
+               tp = list_entry(cull.next, lnet_test_peer_t, tp_list);
 
-               list_del (&tp->tp_list);
-               LIBCFS_FREE(tp, sizeof (*tp));
+               list_del(&tp->tp_list);
+               LIBCFS_FREE(tp, sizeof(*tp));
        }
        return 0;
 }
 
 static int
-fail_peer (lnet_nid_t nid, int outgoing)
+fail_peer(lnet_nid_t nid, int outgoing)
 {
        lnet_test_peer_t *tp;
        struct list_head       *el;
@@ -109,13 +108,13 @@ fail_peer (lnet_nid_t nid, int outgoing)
        struct list_head        cull;
        int            fail = 0;
 
-       INIT_LIST_HEAD (&cull);
+       INIT_LIST_HEAD(&cull);
 
        /* NB: use lnet_net_lock(0) to serialize operations on test peers */
        lnet_net_lock(0);
 
-       list_for_each_safe (el, next, &the_lnet.ln_test_peers) {
-               tp = list_entry (el, lnet_test_peer_t, tp_list);
+       list_for_each_safe(el, next, &the_lnet.ln_test_peers) {
+               tp = list_entry(el, lnet_test_peer_t, tp_list);
 
                if (tp->tp_threshold == 0) {
                        /* zombie entry */
@@ -123,8 +122,8 @@ fail_peer (lnet_nid_t nid, int outgoing)
                                /* only cull zombies on outgoing tests,
                                 * since we may be at interrupt priority on
                                 * incoming messages. */
-                               list_del (&tp->tp_list);
-                               list_add (&tp->tp_list, &cull);
+                               list_del(&tp->tp_list);
+                               list_add(&tp->tp_list, &cull);
                        }
                        continue;
                }
@@ -138,8 +137,8 @@ fail_peer (lnet_nid_t nid, int outgoing)
                                if (outgoing &&
                                    tp->tp_threshold == 0) {
                                        /* see above */
-                                       list_del (&tp->tp_list);
-                                       list_add (&tp->tp_list, &cull);
+                                       list_del(&tp->tp_list);
+                                       list_add(&tp->tp_list, &cull);
                                }
                        }
                        break;
@@ -148,30 +147,30 @@ fail_peer (lnet_nid_t nid, int outgoing)
 
        lnet_net_unlock(0);
 
-       while (!list_empty (&cull)) {
-               tp = list_entry (cull.next, lnet_test_peer_t, tp_list);
-               list_del (&tp->tp_list);
+       while (!list_empty(&cull)) {
+               tp = list_entry(cull.next, lnet_test_peer_t, tp_list);
+               list_del(&tp->tp_list);
 
-               LIBCFS_FREE(tp, sizeof (*tp));
+               LIBCFS_FREE(tp, sizeof(*tp));
        }
 
-       return (fail);
+       return fail;
 }
 
 unsigned int
-lnet_iov_nob (unsigned int niov, struct iovec *iov)
+lnet_iov_nob(unsigned int niov, struct iovec *iov)
 {
        unsigned int nob = 0;
 
        while (niov-- > 0)
                nob += (iov++)->iov_len;
 
-       return (nob);
+       return nob;
 }
 EXPORT_SYMBOL(lnet_iov_nob);
 
 void
-lnet_copy_iov2iov (unsigned int ndiov, struct iovec *diov, unsigned int doffset,
+lnet_copy_iov2iov(unsigned int ndiov, struct iovec *diov, unsigned int doffset,
                   unsigned int nsiov, struct iovec *siov, unsigned int soffset,
                   unsigned int nob)
 {
@@ -182,31 +181,31 @@ lnet_copy_iov2iov (unsigned int ndiov, struct iovec *diov, unsigned int doffset,
                return;
 
        /* skip complete frags before 'doffset' */
-       LASSERT (ndiov > 0);
+       LASSERT(ndiov > 0);
        while (doffset >= diov->iov_len) {
                doffset -= diov->iov_len;
                diov++;
                ndiov--;
-               LASSERT (ndiov > 0);
+               LASSERT(ndiov > 0);
        }
 
        /* skip complete frags before 'soffset' */
-       LASSERT (nsiov > 0);
+       LASSERT(nsiov > 0);
        while (soffset >= siov->iov_len) {
                soffset -= siov->iov_len;
                siov++;
                nsiov--;
-               LASSERT (nsiov > 0);
+               LASSERT(nsiov > 0);
        }
 
        do {
-               LASSERT (ndiov > 0);
-               LASSERT (nsiov > 0);
+               LASSERT(ndiov > 0);
+               LASSERT(nsiov > 0);
                this_nob = MIN(diov->iov_len - doffset,
                               siov->iov_len - soffset);
                this_nob = MIN(this_nob, nob);
 
-               memcpy ((char *)diov->iov_base + doffset,
+               memcpy((char *)diov->iov_base + doffset,
                        (char *)siov->iov_base + soffset, this_nob);
                nob -= this_nob;
 
@@ -230,7 +229,7 @@ lnet_copy_iov2iov (unsigned int ndiov, struct iovec *diov, unsigned int doffset,
 EXPORT_SYMBOL(lnet_copy_iov2iov);
 
 int
-lnet_extract_iov (int dst_niov, struct iovec *dst,
+lnet_extract_iov(int dst_niov, struct iovec *dst,
                  int src_niov, struct iovec *src,
                  unsigned int offset, unsigned int len)
 {
@@ -241,27 +240,27 @@ lnet_extract_iov (int dst_niov, struct iovec *dst,
        unsigned int    niov;
 
        if (len == 0)                      /* no data => */
-               return (0);                  /* no frags */
+               return 0;                    /* no frags */
 
-       LASSERT (src_niov > 0);
+       LASSERT(src_niov > 0);
        while (offset >= src->iov_len) {      /* skip initial frags */
                offset -= src->iov_len;
                src_niov--;
                src++;
-               LASSERT (src_niov > 0);
+               LASSERT(src_niov > 0);
        }
 
        niov = 1;
        for (;;) {
-               LASSERT (src_niov > 0);
-               LASSERT ((int)niov <= dst_niov);
+               LASSERT(src_niov > 0);
+               LASSERT((int)niov <= dst_niov);
 
                frag_len = src->iov_len - offset;
                dst->iov_base = ((char *)src->iov_base) + offset;
 
                if (len <= frag_len) {
                        dst->iov_len = len;
-                       return (niov);
+                       return niov;
                }
 
                dst->iov_len = frag_len;
@@ -278,21 +277,21 @@ EXPORT_SYMBOL(lnet_extract_iov);
 
 
 unsigned int
-lnet_kiov_nob (unsigned int niov, lnet_kiov_t *kiov)
+lnet_kiov_nob(unsigned int niov, lnet_kiov_t *kiov)
 {
        unsigned int  nob = 0;
 
        while (niov-- > 0)
                nob += (kiov++)->kiov_len;
 
-       return (nob);
+       return nob;
 }
 EXPORT_SYMBOL(lnet_kiov_nob);
 
 void
-lnet_copy_kiov2kiov (unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset,
-                    unsigned int nsiov, lnet_kiov_t *siov, unsigned int soffset,
-                    unsigned int nob)
+lnet_copy_kiov2kiov(unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset,
+                   unsigned int nsiov, lnet_kiov_t *siov, unsigned int soffset,
+                   unsigned int nob)
 {
        /* NB diov, siov are READ-ONLY */
        unsigned int    this_nob;
@@ -302,27 +301,27 @@ lnet_copy_kiov2kiov (unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset
        if (nob == 0)
                return;
 
-       LASSERT (!in_interrupt ());
+       LASSERT(!in_interrupt());
 
-       LASSERT (ndiov > 0);
+       LASSERT(ndiov > 0);
        while (doffset >= diov->kiov_len) {
                doffset -= diov->kiov_len;
                diov++;
                ndiov--;
-               LASSERT (ndiov > 0);
+               LASSERT(ndiov > 0);
        }
 
-       LASSERT (nsiov > 0);
+       LASSERT(nsiov > 0);
        while (soffset >= siov->kiov_len) {
                soffset -= siov->kiov_len;
                siov++;
                nsiov--;
-               LASSERT (nsiov > 0);
+               LASSERT(nsiov > 0);
        }
 
        do {
-               LASSERT (ndiov > 0);
-               LASSERT (nsiov > 0);
+               LASSERT(ndiov > 0);
+               LASSERT(nsiov > 0);
                this_nob = MIN(diov->kiov_len - doffset,
                               siov->kiov_len - soffset);
                this_nob = MIN(this_nob, nob);
@@ -338,7 +337,7 @@ lnet_copy_kiov2kiov (unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset
                 * However in practice at least one of the kiovs will be mapped
                 * kernel pages and the map/unmap will be NOOPs */
 
-               memcpy (daddr, saddr, this_nob);
+               memcpy(daddr, saddr, this_nob);
                nob -= this_nob;
 
                if (diov->kiov_len > doffset + this_nob) {
@@ -372,9 +371,9 @@ lnet_copy_kiov2kiov (unsigned int ndiov, lnet_kiov_t *diov, unsigned int doffset
 EXPORT_SYMBOL(lnet_copy_kiov2kiov);
 
 void
-lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov, unsigned int iovoffset,
-                   unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffset,
-                   unsigned int nob)
+lnet_copy_kiov2iov(unsigned int niov, struct iovec *iov, unsigned int iovoffset,
+                  unsigned int nkiov, lnet_kiov_t *kiov,
+                  unsigned int kiovoffset, unsigned int nob)
 {
        /* NB iov, kiov are READ-ONLY */
        unsigned int    this_nob;
@@ -383,27 +382,27 @@ lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov, unsigned int iovoffset
        if (nob == 0)
                return;
 
-       LASSERT (!in_interrupt ());
+       LASSERT(!in_interrupt());
 
-       LASSERT (niov > 0);
+       LASSERT(niov > 0);
        while (iovoffset >= iov->iov_len) {
                iovoffset -= iov->iov_len;
                iov++;
                niov--;
-               LASSERT (niov > 0);
+               LASSERT(niov > 0);
        }
 
-       LASSERT (nkiov > 0);
+       LASSERT(nkiov > 0);
        while (kiovoffset >= kiov->kiov_len) {
                kiovoffset -= kiov->kiov_len;
                kiov++;
                nkiov--;
-               LASSERT (nkiov > 0);
+               LASSERT(nkiov > 0);
        }
 
        do {
-               LASSERT (niov > 0);
-               LASSERT (nkiov > 0);
+               LASSERT(niov > 0);
+               LASSERT(nkiov > 0);
                this_nob = MIN(iov->iov_len - iovoffset,
                               kiov->kiov_len - kiovoffset);
                this_nob = MIN(this_nob, nob);
@@ -412,7 +411,7 @@ lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov, unsigned int iovoffset
                        addr = ((char *)kmap(kiov->kiov_page)) +
                                kiov->kiov_offset + kiovoffset;
 
-               memcpy ((char *)iov->iov_base + iovoffset, addr, this_nob);
+               memcpy((char *)iov->iov_base + iovoffset, addr, this_nob);
                nob -= this_nob;
 
                if (iov->iov_len > iovoffset + this_nob) {
@@ -442,9 +441,10 @@ lnet_copy_kiov2iov (unsigned int niov, struct iovec *iov, unsigned int iovoffset
 EXPORT_SYMBOL(lnet_copy_kiov2iov);
 
 void
-lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffset,
-                   unsigned int niov, struct iovec *iov, unsigned int iovoffset,
-                   unsigned int nob)
+lnet_copy_iov2kiov(unsigned int nkiov, lnet_kiov_t *kiov,
+                  unsigned int kiovoffset, unsigned int niov,
+                  struct iovec *iov, unsigned int iovoffset,
+                  unsigned int nob)
 {
        /* NB kiov, iov are READ-ONLY */
        unsigned int    this_nob;
@@ -453,27 +453,27 @@ lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffs
        if (nob == 0)
                return;
 
-       LASSERT (!in_interrupt ());
+       LASSERT(!in_interrupt());
 
-       LASSERT (nkiov > 0);
+       LASSERT(nkiov > 0);
        while (kiovoffset >= kiov->kiov_len) {
                kiovoffset -= kiov->kiov_len;
                kiov++;
                nkiov--;
-               LASSERT (nkiov > 0);
+               LASSERT(nkiov > 0);
        }
 
-       LASSERT (niov > 0);
+       LASSERT(niov > 0);
        while (iovoffset >= iov->iov_len) {
                iovoffset -= iov->iov_len;
                iov++;
                niov--;
-               LASSERT (niov > 0);
+               LASSERT(niov > 0);
        }
 
        do {
-               LASSERT (nkiov > 0);
-               LASSERT (niov > 0);
+               LASSERT(nkiov > 0);
+               LASSERT(niov > 0);
                this_nob = MIN(kiov->kiov_len - kiovoffset,
                               iov->iov_len - iovoffset);
                this_nob = MIN(this_nob, nob);
@@ -482,7 +482,7 @@ lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffs
                        addr = ((char *)kmap(kiov->kiov_page)) +
                                kiov->kiov_offset + kiovoffset;
 
-               memcpy (addr, (char *)iov->iov_base + iovoffset, this_nob);
+               memcpy(addr, (char *)iov->iov_base + iovoffset, this_nob);
                nob -= this_nob;
 
                if (kiov->kiov_len > kiovoffset + this_nob) {
@@ -511,7 +511,7 @@ lnet_copy_iov2kiov (unsigned int nkiov, lnet_kiov_t *kiov, unsigned int kiovoffs
 EXPORT_SYMBOL(lnet_copy_iov2kiov);
 
 int
-lnet_extract_kiov (int dst_niov, lnet_kiov_t *dst,
+lnet_extract_kiov(int dst_niov, lnet_kiov_t *dst,
                   int src_niov, lnet_kiov_t *src,
                   unsigned int offset, unsigned int len)
 {
@@ -522,20 +522,20 @@ lnet_extract_kiov (int dst_niov, lnet_kiov_t *dst,
        unsigned int    niov;
 
        if (len == 0)                      /* no data => */
-               return (0);                  /* no frags */
+               return 0;                    /* no frags */
 
-       LASSERT (src_niov > 0);
+       LASSERT(src_niov > 0);
        while (offset >= src->kiov_len) {      /* skip initial frags */
                offset -= src->kiov_len;
                src_niov--;
                src++;
-               LASSERT (src_niov > 0);
+               LASSERT(src_niov > 0);
        }
 
        niov = 1;
        for (;;) {
-               LASSERT (src_niov > 0);
-               LASSERT ((int)niov <= dst_niov);
+               LASSERT(src_niov > 0);
+               LASSERT((int)niov <= dst_niov);
 
                frag_len = src->kiov_len - offset;
                dst->kiov_page = src->kiov_page;
@@ -543,12 +543,13 @@ lnet_extract_kiov (int dst_niov, lnet_kiov_t *dst,
 
                if (len <= frag_len) {
                        dst->kiov_len = len;
-                       LASSERT (dst->kiov_offset + dst->kiov_len <= PAGE_CACHE_SIZE);
-                       return (niov);
+                       LASSERT(dst->kiov_offset + dst->kiov_len
+                                            <= PAGE_CACHE_SIZE);
+                       return niov;
                }
 
                dst->kiov_len = frag_len;
-               LASSERT (dst->kiov_offset + dst->kiov_len <= PAGE_CACHE_SIZE);
+               LASSERT(dst->kiov_offset + dst->kiov_len <= PAGE_CACHE_SIZE);
 
                len -= frag_len;
                dst++;
@@ -569,8 +570,8 @@ lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
        lnet_kiov_t  *kiov = NULL;
        int        rc;
 
-       LASSERT (!in_interrupt ());
-       LASSERT (mlen == 0 || msg != NULL);
+       LASSERT(!in_interrupt());
+       LASSERT(mlen == 0 || msg != NULL);
 
        if (msg != NULL) {
                LASSERT(msg->msg_receiving);
@@ -587,8 +588,8 @@ lnet_ni_recv(lnet_ni_t *ni, void *private, lnet_msg_t *msg, int delayed,
                        iov  = msg->msg_iov;
                        kiov = msg->msg_kiov;
 
-                       LASSERT (niov > 0);
-                       LASSERT ((iov == NULL) != (kiov == NULL));
+                       LASSERT(niov > 0);
+                       LASSERT((iov == NULL) != (kiov == NULL));
                }
        }
 
@@ -603,12 +604,12 @@ lnet_setpayloadbuffer(lnet_msg_t *msg)
 {
        lnet_libmd_t *md = msg->msg_md;
 
-       LASSERT (msg->msg_len > 0);
-       LASSERT (!msg->msg_routing);
-       LASSERT (md != NULL);
-       LASSERT (msg->msg_niov == 0);
-       LASSERT (msg->msg_iov == NULL);
-       LASSERT (msg->msg_kiov == NULL);
+       LASSERT(msg->msg_len > 0);
+       LASSERT(!msg->msg_routing);
+       LASSERT(md != NULL);
+       LASSERT(msg->msg_niov == 0);
+       LASSERT(msg->msg_iov == NULL);
+       LASSERT(msg->msg_kiov == NULL);
 
        msg->msg_niov = md->md_niov;
        if ((md->md_options & LNET_MD_KIOV) != 0)
@@ -629,7 +630,7 @@ lnet_prep_send(lnet_msg_t *msg, int type, lnet_process_id_t target,
        if (len != 0)
                lnet_setpayloadbuffer(msg);
 
-       memset (&msg->msg_hdr, 0, sizeof (msg->msg_hdr));
+       memset(&msg->msg_hdr, 0, sizeof(msg->msg_hdr));
        msg->msg_hdr.type          = cpu_to_le32(type);
        msg->msg_hdr.dest_nid       = cpu_to_le64(target.nid);
        msg->msg_hdr.dest_pid       = cpu_to_le32(target.pid);
@@ -644,8 +645,8 @@ lnet_ni_send(lnet_ni_t *ni, lnet_msg_t *msg)
        void   *priv = msg->msg_private;
        int     rc;
 
-       LASSERT (!in_interrupt ());
-       LASSERT (LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND ||
+       LASSERT(!in_interrupt());
+       LASSERT(LNET_NETTYP(LNET_NIDNET(ni->ni_nid)) == LOLND ||
                 (msg->msg_txcredit && msg->msg_peertxcredit));
 
        rc = (ni->ni_lnd->lnd_send)(ni, priv, msg);
@@ -698,12 +699,12 @@ lnet_ni_query_locked(lnet_ni_t *ni, lnet_peer_t *lp)
 
 /* NB: always called with lnet_net_lock held */
 static inline int
-lnet_peer_is_alive (lnet_peer_t *lp, cfs_time_t now)
+lnet_peer_is_alive(lnet_peer_t *lp, cfs_time_t now)
 {
        int     alive;
        cfs_time_t deadline;
 
-       LASSERT (lnet_peer_aliveness_enabled(lp));
+       LASSERT(lnet_peer_aliveness_enabled(lp));
 
        /* Trust lnet_notify() if it has more recent aliveness news, but
         * ignore the initial assumed death (see lnet_peers_start_down()).
@@ -731,7 +732,7 @@ lnet_peer_is_alive (lnet_peer_t *lp, cfs_time_t now)
 /* NB: returns 1 when alive, 0 when dead, negative when error;
  *     may drop the lnet_net_lock */
 int
-lnet_peer_alive_locked (lnet_peer_t *lp)
+lnet_peer_alive_locked(lnet_peer_t *lp)
 {
        cfs_time_t now = cfs_time_current();
 
@@ -809,7 +810,7 @@ lnet_post_send_locked(lnet_msg_t *msg, int do_send)
        }
 
        if (!msg->msg_peertxcredit) {
-               LASSERT ((lp->lp_txcredits < 0) ==
+               LASSERT((lp->lp_txcredits < 0) ==
                         !list_empty(&lp->lp_txq));
 
                msg->msg_peertxcredit = 1;
@@ -873,7 +874,7 @@ lnet_msg2bufpool(lnet_msg_t *msg)
 }
 
 int
-lnet_post_routed_recv_locked (lnet_msg_t *msg, int do_recv)
+lnet_post_routed_recv_locked(lnet_msg_t *msg, int do_recv)
 {
        /* lnet_parse is going to lnet_net_unlock immediately after this, so it
         * sets do_recv FALSE and I don't do the unlock/send/lock bit.  I
@@ -882,18 +883,18 @@ lnet_post_routed_recv_locked (lnet_msg_t *msg, int do_recv)
        lnet_rtrbufpool_t   *rbp;
        lnet_rtrbuf_t       *rb;
 
-       LASSERT (msg->msg_iov == NULL);
-       LASSERT (msg->msg_kiov == NULL);
-       LASSERT (msg->msg_niov == 0);
-       LASSERT (msg->msg_routing);
-       LASSERT (msg->msg_receiving);
-       LASSERT (!msg->msg_sending);
+       LASSERT(msg->msg_iov == NULL);
+       LASSERT(msg->msg_kiov == NULL);
+       LASSERT(msg->msg_niov == 0);
+       LASSERT(msg->msg_routing);
+       LASSERT(msg->msg_receiving);
+       LASSERT(!msg->msg_sending);
 
        /* non-lnet_parse callers only receive delayed messages */
        LASSERT(!do_recv || msg->msg_rx_delayed);
 
        if (!msg->msg_peerrtrcredit) {
-               LASSERT ((lp->lp_rtrcredits < 0) ==
+               LASSERT((lp->lp_rtrcredits < 0) ==
                         !list_empty(&lp->lp_rtrq));
 
                msg->msg_peerrtrcredit = 1;
@@ -913,7 +914,7 @@ lnet_post_routed_recv_locked (lnet_msg_t *msg, int do_recv)
        rbp = lnet_msg2bufpool(msg);
 
        if (!msg->msg_rtrcredit) {
-               LASSERT ((rbp->rbp_credits < 0) ==
+               LASSERT((rbp->rbp_credits < 0) ==
                         !list_empty(&rbp->rbp_msgs));
 
                msg->msg_rtrcredit = 1;
@@ -930,7 +931,7 @@ lnet_post_routed_recv_locked (lnet_msg_t *msg, int do_recv)
                }
        }
 
-       LASSERT (!list_empty(&rbp->rbp_bufs));
+       LASSERT(!list_empty(&rbp->rbp_bufs));
        rb = list_entry(rbp->rbp_bufs.next, lnet_rtrbuf_t, rb_list);
        list_del(&rb->rb_list);
 
@@ -985,7 +986,7 @@ lnet_return_tx_credits_locked(lnet_msg_t *msg)
                        !list_empty(&txpeer->lp_txq));
 
                txpeer->lp_txqnob -= msg->msg_len + sizeof(lnet_hdr_t);
-               LASSERT (txpeer->lp_txqnob >= 0);
+               LASSERT(txpeer->lp_txqnob >= 0);
 
                txpeer->lp_txcredits++;
                if (txpeer->lp_txcredits <= 0) {
@@ -1020,11 +1021,11 @@ lnet_return_rx_credits_locked(lnet_msg_t *msg)
                /* NB If a msg ever blocks for a buffer in rbp_msgs, it stays
                 * there until it gets one allocated, or aborts the wait
                 * itself */
-               LASSERT (msg->msg_kiov != NULL);
+               LASSERT(msg->msg_kiov != NULL);
 
                rb = list_entry(msg->msg_kiov, lnet_rtrbuf_t, rb_kiov[0]);
                rbp = rb->rb_pool;
-               LASSERT (rbp == lnet_msg2bufpool(msg));
+               LASSERT(rbp == lnet_msg2bufpool(msg));
 
                msg->msg_kiov = NULL;
                msg->msg_rtrcredit = 0;
@@ -1172,10 +1173,10 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
         * but we might want to use pre-determined router for ACK/REPLY
         * in the future */
        /* NB: ni != NULL == interface pre-determined (ACK/REPLY) */
-       LASSERT (msg->msg_txpeer == NULL);
-       LASSERT (!msg->msg_sending);
-       LASSERT (!msg->msg_target_is_router);
-       LASSERT (!msg->msg_receiving);
+       LASSERT(msg->msg_txpeer == NULL);
+       LASSERT(!msg->msg_sending);
+       LASSERT(!msg->msg_target_is_router);
+       LASSERT(!msg->msg_receiving);
 
        msg->msg_sending = 1;
 
@@ -1200,7 +1201,7 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
                                      libcfs_nid2str(src_nid));
                        return -EINVAL;
                }
-               LASSERT (!msg->msg_routing);
+               LASSERT(!msg->msg_routing);
        }
 
        /* Is this for someone on a local network? */
@@ -1249,7 +1250,7 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
                        /* ENOMEM or shutting down */
                        return rc;
                }
-               LASSERT (lp->lp_ni == src_ni);
+               LASSERT(lp->lp_ni == src_ni);
        } else {
                /* sending to a remote network */
                lp = lnet_find_route_locked(src_ni, dst_nid, rtr_nid);
@@ -1290,7 +1291,7 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
                        src_ni = lp->lp_ni;
                        src_nid = src_ni->ni_nid;
                } else {
-                       LASSERT (src_ni == lp->lp_ni);
+                       LASSERT(src_ni == lp->lp_ni);
                        lnet_ni_decref_locked(src_ni, cpt);
                }
 
@@ -1311,9 +1312,9 @@ lnet_send(lnet_nid_t src_nid, lnet_msg_t *msg, lnet_nid_t rtr_nid)
 
        /* 'lp' is our best choice of peer */
 
-       LASSERT (!msg->msg_peertxcredit);
-       LASSERT (!msg->msg_txcredit);
-       LASSERT (msg->msg_txpeer == NULL);
+       LASSERT(!msg->msg_peertxcredit);
+       LASSERT(!msg->msg_txcredit);
+       LASSERT(msg->msg_txpeer == NULL);
 
        msg->msg_txpeer = lp;              /* msg takes my ref on lp */
 
@@ -1509,7 +1510,7 @@ lnet_parse_reply(lnet_ni_t *ni, lnet_msg_t *msg)
                return ENOENT;            /* +ve: OK but no match */
        }
 
-       LASSERT (md->md_offset == 0);
+       LASSERT(md->md_offset == 0);
 
        rlength = hdr->payload_length;
        mlength = MIN(rlength, (int)md->md_length);
@@ -1614,31 +1615,31 @@ lnet_parse_forward_locked(lnet_ni_t *ni, lnet_msg_t *msg)
 }
 
 char *
-lnet_msgtyp2str (int type)
+lnet_msgtyp2str(int type)
 {
        switch (type) {
        case LNET_MSG_ACK:
-               return ("ACK");
+               return "ACK";
        case LNET_MSG_PUT:
-               return ("PUT");
+               return "PUT";
        case LNET_MSG_GET:
-               return ("GET");
+               return "GET";
        case LNET_MSG_REPLY:
-               return ("REPLY");
+               return "REPLY";
        case LNET_MSG_HELLO:
-               return ("HELLO");
+               return "HELLO";
        default:
-               return ("<UNKNOWN>");
+               return "<UNKNOWN>";
        }
 }
 EXPORT_SYMBOL(lnet_msgtyp2str);
 
 void
-lnet_print_hdr(lnet_hdr_t * hdr)
+lnet_print_hdr(lnet_hdr_t *hdr)
 {
        lnet_process_id_t src = {0};
        lnet_process_id_t dst = {0};
-       char *type_str = lnet_msgtyp2str (hdr->type);
+       char *type_str = lnet_msgtyp2str(hdr->type);
 
        src.nid = hdr->src_nid;
        src.pid = hdr->src_pid;
@@ -1709,7 +1710,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
        __u32     payload_length;
        __u32     type;
 
-       LASSERT (!in_interrupt ());
+       LASSERT(!in_interrupt());
 
        type = le32_to_cpu(hdr->type);
        src_nid = le64_to_cpu(hdr->src_nid);
@@ -1734,7 +1735,8 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
 
        case LNET_MSG_PUT:
        case LNET_MSG_REPLY:
-               if (payload_length > (__u32)(for_me ? LNET_MAX_PAYLOAD : LNET_MTU)) {
+               if (payload_length >
+                  (__u32)(for_me ? LNET_MAX_PAYLOAD : LNET_MTU)) {
                        CERROR("%s, src %s: bad %s payload %d "
                               "(%d max expected)\n",
                               libcfs_nid2str(from_nid),
@@ -1772,7 +1774,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
        if (!for_me) {
                if (LNET_NIDNET(dest_nid) == LNET_NIDNET(ni->ni_nid)) {
                        /* should have gone direct */
-                       CERROR ("%s, src %s: Bad dest nid %s "
+                       CERROR("%s, src %s: Bad dest nid %s "
                                "(should have been sent direct)\n",
                                libcfs_nid2str(from_nid),
                                libcfs_nid2str(src_nid),
@@ -1783,7 +1785,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
                if (lnet_islocalnid(dest_nid)) {
                        /* dest is another local NI; sender should have used
                         * this node's NID on its own network */
-                       CERROR ("%s, src %s: Bad dest nid %s "
+                       CERROR("%s, src %s: Bad dest nid %s "
                                "(it's my nid but on a different network)\n",
                                libcfs_nid2str(from_nid),
                                libcfs_nid2str(src_nid),
@@ -1792,7 +1794,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
                }
 
                if (rdma_req && type == LNET_MSG_GET) {
-                       CERROR ("%s, src %s: Bad optimized GET for %s "
+                       CERROR("%s, src %s: Bad optimized GET for %s "
                                "(final destination must be me)\n",
                                libcfs_nid2str(from_nid),
                                libcfs_nid2str(src_nid),
@@ -1801,7 +1803,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
                }
 
                if (!the_lnet.ln_routing) {
-                       CERROR ("%s, src %s: Dropping message for %s "
+                       CERROR("%s, src %s: Dropping message for %s "
                                "(routing not enabled)\n",
                                libcfs_nid2str(from_nid),
                                libcfs_nid2str(src_nid),
@@ -1813,9 +1815,8 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
        /* Message looks OK; we're not going to return an error, so we MUST
         * call back lnd_recv() come what may... */
 
-       if (!list_empty (&the_lnet.ln_test_peers) && /* normally we don't */
-           fail_peer (src_nid, 0))          /* shall we now? */
-       {
+       if (!list_empty(&the_lnet.ln_test_peers) && /* normally we don't */
+           fail_peer(src_nid, 0)) {         /* shall we now? */
                CERROR("%s, src %s: Dropping %s to simulate failure\n",
                       libcfs_nid2str(from_nid), libcfs_nid2str(src_nid),
                       lnet_msgtyp2str(type));
@@ -1830,7 +1831,9 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
                goto drop;
        }
 
-       /* msg zeroed in lnet_msg_alloc; i.e. flags all clear, pointers NULL etc */
+       /* msg zeroed in lnet_msg_alloc;
+        * i.e. flags all clear, pointers NULL etc
+        */
 
        msg->msg_type = type;
        msg->msg_private = private;
@@ -1906,7 +1909,7 @@ lnet_parse(lnet_ni_t *ni, lnet_hdr_t *hdr, lnet_nid_t from_nid,
        if (rc == 0)
                return 0;
 
-       LASSERT (rc == ENOENT);
+       LASSERT(rc == ENOENT);
 
  free_drop:
        LASSERT(msg->msg_md == NULL);
@@ -2047,12 +2050,11 @@ LNetPut(lnet_nid_t self, lnet_handle_md_t mdh, lnet_ack_req_t ack,
        int                     cpt;
        int                     rc;
 
-       LASSERT (the_lnet.ln_init);
-       LASSERT (the_lnet.ln_refcount > 0);
+       LASSERT(the_lnet.ln_init);
+       LASSERT(the_lnet.ln_refcount > 0);
 
-       if (!list_empty (&the_lnet.ln_test_peers) && /* normally we don't */
-           fail_peer (target.nid, 1))    /* shall we now? */
-       {
+       if (!list_empty(&the_lnet.ln_test_peers) && /* normally we don't */
+           fail_peer(target.nid, 1)) { /* shall we now? */
                CERROR("Dropping PUT to %s: simulated failure\n",
                       libcfs_id2str(target));
                return -EIO;
@@ -2113,9 +2115,9 @@ LNetPut(lnet_nid_t self, lnet_handle_md_t mdh, lnet_ack_req_t ack,
 
        rc = lnet_send(self, msg, LNET_NID_ANY);
        if (rc != 0) {
-               CNETERR( "Error sending PUT to %s: %d\n",
+               CNETERR("Error sending PUT to %s: %d\n",
                       libcfs_id2str(target), rc);
-               lnet_finalize (NULL, msg, rc);
+               lnet_finalize(NULL, msg, rc);
        }
 
        /* completion will be signalled by an event */
@@ -2124,7 +2126,7 @@ LNetPut(lnet_nid_t self, lnet_handle_md_t mdh, lnet_ack_req_t ack,
 EXPORT_SYMBOL(LNetPut);
 
 lnet_msg_t *
-lnet_create_reply_msg (lnet_ni_t *ni, lnet_msg_t *getmsg)
+lnet_create_reply_msg(lnet_ni_t *ni, lnet_msg_t *getmsg)
 {
        /* The LND can DMA direct to the GET md (i.e. no REPLY msg).  This
         * returns a msg for the LND to pass to lnet_finalize() when the sink
@@ -2144,16 +2146,16 @@ lnet_create_reply_msg (lnet_ni_t *ni, lnet_msg_t *getmsg)
        cpt = lnet_cpt_of_cookie(getmd->md_lh.lh_cookie);
        lnet_res_lock(cpt);
 
-       LASSERT (getmd->md_refcount > 0);
+       LASSERT(getmd->md_refcount > 0);
 
        if (msg == NULL) {
-               CERROR ("%s: Dropping REPLY from %s: can't allocate msg\n",
+               CERROR("%s: Dropping REPLY from %s: can't allocate msg\n",
                        libcfs_nid2str(ni->ni_nid), libcfs_id2str(peer_id));
                goto drop;
        }
 
        if (getmd->md_threshold == 0) {
-               CERROR ("%s: Dropping REPLY from %s for inactive MD %p\n",
+               CERROR("%s: Dropping REPLY from %s for inactive MD %p\n",
                        libcfs_nid2str(ni->ni_nid), libcfs_id2str(peer_id),
                        getmd);
                lnet_res_unlock(cpt);
@@ -2205,13 +2207,13 @@ lnet_set_reply_msg_len(lnet_ni_t *ni, lnet_msg_t *reply, unsigned int len)
 {
        /* Set the REPLY length, now the RDMA that elides the REPLY message has
         * completed and I know it. */
-       LASSERT (reply != NULL);
-       LASSERT (reply->msg_type == LNET_MSG_GET);
-       LASSERT (reply->msg_ev.type == LNET_EVENT_REPLY);
+       LASSERT(reply != NULL);
+       LASSERT(reply->msg_type == LNET_MSG_GET);
+       LASSERT(reply->msg_ev.type == LNET_EVENT_REPLY);
 
        /* NB I trusted my peer to RDMA.  If she tells me she's written beyond
         * the end of my buffer, I might as well be dead. */
-       LASSERT (len <= reply->msg_ev.mlength);
+       LASSERT(len <= reply->msg_ev.mlength);
 
        reply->msg_ev.mlength = len;
 }
@@ -2229,7 +2231,8 @@ EXPORT_SYMBOL(lnet_set_reply_msg_len);
  *
  * \param self,target,portal,match_bits,offset See the discussion in LNetPut().
  * \param mdh A handle for the MD that describes the memory into which the
- * requested data will be received. The MD must be "free floating" (See LNetMDBind()).
+ * requested data will be received. The MD must be "free floating"
+ * (See LNetMDBind()).
  *
  * \retval  0      Success, and only in this case events will be generated
  * and logged to EQ (if it exists) of the MD.
@@ -2247,12 +2250,11 @@ LNetGet(lnet_nid_t self, lnet_handle_md_t mdh,
        int                     cpt;
        int                     rc;
 
-       LASSERT (the_lnet.ln_init);
-       LASSERT (the_lnet.ln_refcount > 0);
+       LASSERT(the_lnet.ln_init);
+       LASSERT(the_lnet.ln_refcount > 0);
 
-       if (!list_empty (&the_lnet.ln_test_peers) && /* normally we don't */
-           fail_peer (target.nid, 1))    /* shall we now? */
-       {
+       if (!list_empty(&the_lnet.ln_test_peers) && /* normally we don't */
+           fail_peer(target.nid, 1)) {   /* shall we now? */
                CERROR("Dropping GET to %s: simulated failure\n",
                       libcfs_id2str(target));
                return -EIO;
@@ -2307,9 +2309,9 @@ LNetGet(lnet_nid_t self, lnet_handle_md_t mdh,
 
        rc = lnet_send(self, msg, LNET_NID_ANY);
        if (rc < 0) {
-               CNETERR( "Error sending GET to %s: %d\n",
+               CNETERR("Error sending GET to %s: %d\n",
                       libcfs_id2str(target), rc);
-               lnet_finalize (NULL, msg, rc);
+               lnet_finalize(NULL, msg, rc);
        }
 
        /* completion will be signalled by an event */
@@ -2348,12 +2350,12 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp)
         * keep order 0 free for 0@lo and order 1 free for a local NID
         * match */
 
-       LASSERT (the_lnet.ln_init);
-       LASSERT (the_lnet.ln_refcount > 0);
+       LASSERT(the_lnet.ln_init);
+       LASSERT(the_lnet.ln_refcount > 0);
 
        cpt = lnet_net_lock_current();
 
-       list_for_each (e, &the_lnet.ln_nis) {
+       list_for_each(e, &the_lnet.ln_nis) {
                ni = list_entry(e, lnet_ni_t, ni_list);
 
                if (ni->ni_nid == dstnid) {
@@ -2390,7 +2392,7 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp)
                        lnet_route_t *route;
                        lnet_route_t *shortest = NULL;
 
-                       LASSERT (!list_empty(&rnet->lrn_routes));
+                       LASSERT(!list_empty(&rnet->lrn_routes));
 
                        list_for_each_entry(route, &rnet->lrn_routes,
                                                lr_list) {
@@ -2399,7 +2401,7 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp)
                                        shortest = route;
                        }
 
-                       LASSERT (shortest != NULL);
+                       LASSERT(shortest != NULL);
                        hops = shortest->lr_hops;
                        if (srcnidp != NULL)
                                *srcnidp = shortest->lr_gateway->lp_ni->ni_nid;
index 670dae34107c5208f3b1c383abdd6ae0c2c58fbe..efc798e01934d795b3b422fd0275c96caf24ffa4 100644 (file)
 #include <linux/lnet/lib-lnet.h>
 
 int
-lolnd_send (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
+lolnd_send(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg)
 {
-       LASSERT (!lntmsg->msg_routing);
-       LASSERT (!lntmsg->msg_target_is_router);
+       LASSERT(!lntmsg->msg_routing);
+       LASSERT(!lntmsg->msg_target_is_router);
 
        return lnet_parse(ni, &lntmsg->msg_hdr, ni->ni_nid, lntmsg, 0);
 }
 
 int
-lolnd_recv (lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
+lolnd_recv(lnet_ni_t *ni, void *private, lnet_msg_t *lntmsg,
            int delayed, unsigned int niov,
            struct iovec *iov, lnet_kiov_t *kiov,
            unsigned int offset, unsigned int mlen, unsigned int rlen)
@@ -89,20 +89,20 @@ static int lolnd_instanced;
 void
 lolnd_shutdown(lnet_ni_t *ni)
 {
-       CDEBUG (D_NET, "shutdown\n");
-       LASSERT (lolnd_instanced);
+       CDEBUG(D_NET, "shutdown\n");
+       LASSERT(lolnd_instanced);
 
        lolnd_instanced = 0;
 }
 
 int
-lolnd_startup (lnet_ni_t *ni)
+lolnd_startup(lnet_ni_t *ni)
 {
-       LASSERT (ni->ni_lnd == &the_lolnd);
-       LASSERT (!lolnd_instanced);
+       LASSERT(ni->ni_lnd == &the_lolnd);
+       LASSERT(!lolnd_instanced);
        lolnd_instanced = 1;
 
-       return (0);
+       return 0;
 }
 
 lnd_t the_lolnd = {
index afb81755cbad19390adddc59a546f4f6445cc401..6db8774ff7b7161f8ec71f90cf4224a08af34ccb 100644 (file)
 #define DEBUG_SUBSYSTEM S_LNET
 #include <linux/lnet/lib-lnet.h>
 
-static int config_on_load = 0;
+static int config_on_load;
 CFS_MODULE_PARM(config_on_load, "i", int, 0444,
                "configure network at module load");
 
 static struct mutex lnet_config_mutex;
 
 int
-lnet_configure (void *arg)
+lnet_configure(void *arg)
 {
        /* 'arg' only there so I can be passed to cfs_create_thread() */
        int    rc = 0;
@@ -64,7 +64,7 @@ lnet_configure (void *arg)
 }
 
 int
-lnet_unconfigure (void)
+lnet_unconfigure(void)
 {
        int   refcount;
 
@@ -124,7 +124,7 @@ init_lnet(void)
        }
 
        rc = libcfs_register_ioctl(&lnet_ioctl_handler);
-       LASSERT (rc == 0);
+       LASSERT(rc == 0);
 
        if (config_on_load) {
                /* Have to schedule a separate thread to avoid deadlocking
@@ -141,7 +141,7 @@ fini_lnet(void)
        int rc;
 
        rc = libcfs_deregister_ioctl(&lnet_ioctl_handler);
-       LASSERT (rc == 0);
+       LASSERT(rc == 0);
 
        LNetFini();
 }
index 931f6ca25dc72268a11043281d7714bff72b3d99..5e47de36c184526cf09d8293782d135842c77a44 100644 (file)
@@ -30,7 +30,7 @@
 /* This is really lnet_proc.c. You might need to update sanity test 215
  * if any file format is changed. */
 
-static ctl_table_header_t *lnet_table_header = NULL;
+static ctl_table_header_t *lnet_table_header;
 
 #define CTL_LNET        (0x100)
 enum {
@@ -158,7 +158,7 @@ int LL_PROC_PROTO(proc_lnet_routes)
        off = LNET_PROC_HOFF_GET(*ppos);
        ver = LNET_PROC_VER_GET(*ppos);
 
-       LASSERT (!write);
+       LASSERT(!write);
 
        if (*lenp == 0)
                return 0;
@@ -172,11 +172,11 @@ int LL_PROC_PROTO(proc_lnet_routes)
        if (*ppos == 0) {
                s += snprintf(s, tmpstr + tmpsiz - s, "Routing %s\n",
                              the_lnet.ln_routing ? "enabled" : "disabled");
-               LASSERT (tmpstr + tmpsiz - s > 0);
+               LASSERT(tmpstr + tmpsiz - s > 0);
 
                s += snprintf(s, tmpstr + tmpsiz - s, "%-8s %4s %7s %s\n",
                              "net", "hops", "state", "router");
-               LASSERT (tmpstr + tmpsiz - s > 0);
+               LASSERT(tmpstr + tmpsiz - s > 0);
 
                lnet_net_lock(0);
                ver = (unsigned int)the_lnet.ln_remote_nets_version;
@@ -281,7 +281,7 @@ int LL_PROC_PROTO(proc_lnet_routers)
        off = LNET_PROC_HOFF_GET(*ppos);
        ver = LNET_PROC_VER_GET(*ppos);
 
-       LASSERT (!write);
+       LASSERT(!write);
 
        if (*lenp == 0)
                return 0;
@@ -375,7 +375,7 @@ int LL_PROC_PROTO(proc_lnet_routers)
                                              pingsent,
                                              cfs_duration_sec(cfs_time_sub(deadline, now)),
                                              down_ni, libcfs_nid2str(nid));
-                       LASSERT (tmpstr + tmpsiz - s > 0);
+                       LASSERT(tmpstr + tmpsiz - s > 0);
                }
 
                lnet_net_unlock(0);
@@ -437,7 +437,7 @@ int LL_PROC_PROTO(proc_lnet_peers)
                              "%-24s %4s %5s %5s %5s %5s %5s %5s %5s %s\n",
                              "nid", "refs", "state", "last", "max",
                              "rtr", "min", "tx", "min", "queue");
-               LASSERT (tmpstr + tmpsiz - s > 0);
+               LASSERT(tmpstr + tmpsiz - s > 0);
 
                hoff++;
        } else {
@@ -534,7 +534,7 @@ int LL_PROC_PROTO(proc_lnet_peers)
                                      libcfs_nid2str(nid), nrefs, aliveness,
                                      lastalive, maxcr, rtrcr, minrtrcr, txcr,
                                      mintxcr, txqnob);
-                       LASSERT (tmpstr + tmpsiz - s > 0);
+                       LASSERT(tmpstr + tmpsiz - s > 0);
 
                } else { /* peer is NULL */
                        lnet_net_unlock(cpt);
@@ -592,7 +592,7 @@ static int __proc_lnet_buffers(void *data, int write,
        s += snprintf(s, tmpstr + tmpsiz - s,
                      "%5s %5s %7s %7s\n",
                      "pages", "count", "credits", "min");
-       LASSERT (tmpstr + tmpsiz - s > 0);
+       LASSERT(tmpstr + tmpsiz - s > 0);
 
        if (the_lnet.ln_rtrpools == NULL)
                goto out; /* I'm not a router */
@@ -638,7 +638,7 @@ int LL_PROC_PROTO(proc_lnet_nis)
 
        DECLARE_LL_PROC_PPOS_DECL;
 
-       LASSERT (!write);
+       LASSERT(!write);
 
        if (*lenp == 0)
                return 0;
@@ -654,7 +654,7 @@ int LL_PROC_PROTO(proc_lnet_nis)
                              "%-24s %6s %5s %4s %4s %4s %5s %5s %5s\n",
                              "nid", "status", "alive", "refs", "peer",
                              "rtr", "max", "tx", "min");
-               LASSERT (tmpstr + tmpsiz - s > 0);
+               LASSERT(tmpstr + tmpsiz - s > 0);
        } else {
                struct list_head        *n;
                lnet_ni_t        *ni   = NULL;
index ef5064e0055f26bae931f656cd603f5c0db4d2e9..b7613c828e763431c766607604e636f073036f68 100644 (file)
@@ -48,16 +48,17 @@ CFS_MODULE_PARM(brw_inject_errors, "i", int, 0644,
                "# data errors to inject randomly, zero by default");
 
 static void
-brw_client_fini (sfw_test_instance_t *tsi)
+brw_client_fini(sfw_test_instance_t *tsi)
 {
        srpc_bulk_t     *bulk;
        sfw_test_unit_t *tsu;
 
-       LASSERT (tsi->tsi_is_client);
+       LASSERT(tsi->tsi_is_client);
 
-       list_for_each_entry (tsu, &tsi->tsi_units, tsu_list) {
+       list_for_each_entry(tsu, &tsi->tsi_units, tsu_list) {
                bulk = tsu->tsu_private;
-               if (bulk == NULL) continue;
+               if (bulk == NULL)
+                       continue;
 
                srpc_free_bulk(bulk);
                tsu->tsu_private = NULL;
@@ -65,7 +66,7 @@ brw_client_fini (sfw_test_instance_t *tsi)
 }
 
 int
-brw_client_init (sfw_test_instance_t *tsi)
+brw_client_init(sfw_test_instance_t *tsi)
 {
        sfw_session_t    *sn = tsi->tsi_batch->bat_session;
        int               flags;
@@ -130,28 +131,31 @@ brw_client_init (sfw_test_instance_t *tsi)
 #define BRW_MSIZE       sizeof(__u64)
 
 int
-brw_inject_one_error (void)
+brw_inject_one_error(void)
 {
        struct timeval tv;
 
-       if (brw_inject_errors <= 0) return 0;
+       if (brw_inject_errors <= 0)
+               return 0;
 
        do_gettimeofday(&tv);
 
-       if ((tv.tv_usec & 1) == 0) return 0;
+       if ((tv.tv_usec & 1) == 0)
+               return 0;
 
        return brw_inject_errors--;
 }
 
 void
-brw_fill_page (struct page *pg, int pattern, __u64 magic)
+brw_fill_page(struct page *pg, int pattern, __u64 magic)
 {
        char *addr = page_address(pg);
        int   i;
 
-       LASSERT (addr != NULL);
+       LASSERT(addr != NULL);
 
-       if (pattern == LST_BRW_CHECK_NONE) return;
+       if (pattern == LST_BRW_CHECK_NONE)
+               return;
 
        if (magic == BRW_MAGIC)
                magic += brw_inject_one_error();
@@ -169,29 +173,31 @@ brw_fill_page (struct page *pg, int pattern, __u64 magic)
                return;
        }
 
-       LBUG ();
+       LBUG();
        return;
 }
 
 int
-brw_check_page (struct page *pg, int pattern, __u64 magic)
+brw_check_page(struct page *pg, int pattern, __u64 magic)
 {
        char  *addr = page_address(pg);
        __u64  data = 0; /* make compiler happy */
        int    i;
 
-       LASSERT (addr != NULL);
+       LASSERT(addr != NULL);
 
        if (pattern == LST_BRW_CHECK_NONE)
                return 0;
 
        if (pattern == LST_BRW_CHECK_SIMPLE) {
                data = *((__u64 *) addr);
-               if (data != magic) goto bad_data;
+               if (data != magic)
+                       goto bad_data;
 
                addr += PAGE_CACHE_SIZE - BRW_MSIZE;
                data = *((__u64 *) addr);
-               if (data != magic) goto bad_data;
+               if (data != magic)
+                       goto bad_data;
 
                return 0;
        }
@@ -199,22 +205,23 @@ brw_check_page (struct page *pg, int pattern, __u64 magic)
        if (pattern == LST_BRW_CHECK_FULL) {
                for (i = 0; i < PAGE_CACHE_SIZE / BRW_MSIZE; i++) {
                        data = *(((__u64 *) addr) + i);
-                       if (data != magic) goto bad_data;
+                       if (data != magic)
+                               goto bad_data;
                }
 
                return 0;
        }
 
-       LBUG ();
+       LBUG();
 
 bad_data:
-       CERROR ("Bad data in page %p: "LPX64", "LPX64" expected\n",
+       CERROR("Bad data in page %p: "LPX64", "LPX64" expected\n",
                pg, data, magic);
        return 1;
 }
 
 void
-brw_fill_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
+brw_fill_bulk(srpc_bulk_t *bk, int pattern, __u64 magic)
 {
        int      i;
        struct page *pg;
@@ -226,7 +233,7 @@ brw_fill_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
 }
 
 int
-brw_check_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
+brw_check_bulk(srpc_bulk_t *bk, int pattern, __u64 magic)
 {
        int      i;
        struct page *pg;
@@ -234,7 +241,7 @@ brw_check_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
        for (i = 0; i < bk->bk_niov; i++) {
                pg = bk->bk_iovs[i].kiov_page;
                if (brw_check_page(pg, pattern, magic) != 0) {
-                       CERROR ("Bulk page %p (%d/%d) is corrupted!\n",
+                       CERROR("Bulk page %p (%d/%d) is corrupted!\n",
                                pg, i, bk->bk_niov);
                        return 1;
                }
@@ -244,7 +251,7 @@ brw_check_bulk (srpc_bulk_t *bk, int pattern, __u64 magic)
 }
 
 static int
-brw_client_prep_rpc (sfw_test_unit_t *tsu,
+brw_client_prep_rpc(sfw_test_unit_t *tsu,
                     lnet_process_id_t dest, srpc_client_rpc_t **rpcpp)
 {
        srpc_bulk_t      *bulk = tsu->tsu_private;
@@ -302,7 +309,7 @@ brw_client_prep_rpc (sfw_test_unit_t *tsu,
 }
 
 static void
-brw_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
+brw_client_done_rpc(sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
 {
        __u64           magic = BRW_MAGIC;
        sfw_test_instance_t *tsi = tsu->tsu_instance;
@@ -311,10 +318,10 @@ brw_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
        srpc_brw_reply_t    *reply = &msg->msg_body.brw_reply;
        srpc_brw_reqst_t    *reqst = &rpc->crpc_reqstmsg.msg_body.brw_reqst;
 
-       LASSERT (sn != NULL);
+       LASSERT(sn != NULL);
 
        if (rpc->crpc_status != 0) {
-               CERROR ("BRW RPC to %s failed with %d\n",
+               CERROR("BRW RPC to %s failed with %d\n",
                        libcfs_id2str(rpc->crpc_dest), rpc->crpc_status);
                if (!tsi->tsi_stopping) /* rpc could have been aborted */
                        atomic_inc(&sn->sn_brw_errors);
@@ -326,7 +333,7 @@ brw_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
                __swab32s(&reply->brw_status);
        }
 
-       CDEBUG (reply->brw_status ? D_WARNING : D_NET,
+       CDEBUG(reply->brw_status ? D_WARNING : D_NET,
                "BRW RPC to %s finished with brw_status: %d\n",
                libcfs_id2str(rpc->crpc_dest), reply->brw_status);
 
@@ -336,10 +343,11 @@ brw_client_done_rpc (sfw_test_unit_t *tsu, srpc_client_rpc_t *rpc)
                goto out;
        }
 
-       if (reqst->brw_rw == LST_BRW_WRITE) goto out;
+       if (reqst->brw_rw == LST_BRW_WRITE)
+               goto out;
 
        if (brw_check_bulk(&rpc->crpc_bulk, reqst->brw_flags, magic) != 0) {
-               CERROR ("Bulk data from %s is corrupted!\n",
+               CERROR("Bulk data from %s is corrupted!\n",
                        libcfs_id2str(rpc->crpc_dest));
                atomic_inc(&sn->sn_brw_errors);
                rpc->crpc_status = -EBADMSG;
@@ -350,18 +358,19 @@ out:
 }
 
 void
-brw_server_rpc_done (srpc_server_rpc_t *rpc)
+brw_server_rpc_done(srpc_server_rpc_t *rpc)
 {
        srpc_bulk_t *blk = rpc->srpc_bulk;
 
-       if (blk == NULL) return;
+       if (blk == NULL)
+               return;
 
        if (rpc->srpc_status != 0)
-               CERROR ("Bulk transfer %s %s has failed: %d\n",
+               CERROR("Bulk transfer %s %s has failed: %d\n",
                        blk->bk_sink ? "from" : "to",
                        libcfs_id2str(rpc->srpc_peer), rpc->srpc_status);
        else
-               CDEBUG (D_NET, "Transferred %d pages bulk data %s %s\n",
+               CDEBUG(D_NET, "Transferred %d pages bulk data %s %s\n",
                        blk->bk_niov, blk->bk_sink ? "from" : "to",
                        libcfs_id2str(rpc->srpc_peer));
 
@@ -369,21 +378,21 @@ brw_server_rpc_done (srpc_server_rpc_t *rpc)
 }
 
 int
-brw_bulk_ready (srpc_server_rpc_t *rpc, int status)
+brw_bulk_ready(srpc_server_rpc_t *rpc, int status)
 {
        __u64        magic = BRW_MAGIC;
        srpc_brw_reply_t *reply = &rpc->srpc_replymsg.msg_body.brw_reply;
        srpc_brw_reqst_t *reqst;
        srpc_msg_t       *reqstmsg;
 
-       LASSERT (rpc->srpc_bulk != NULL);
-       LASSERT (rpc->srpc_reqstbuf != NULL);
+       LASSERT(rpc->srpc_bulk != NULL);
+       LASSERT(rpc->srpc_reqstbuf != NULL);
 
        reqstmsg = &rpc->srpc_reqstbuf->buf_msg;
        reqst = &reqstmsg->msg_body.brw_reqst;
 
        if (status != 0) {
-               CERROR ("BRW bulk %s failed for RPC from %s: %d\n",
+               CERROR("BRW bulk %s failed for RPC from %s: %d\n",
                        reqst->brw_rw == LST_BRW_READ ? "READ" : "WRITE",
                        libcfs_id2str(rpc->srpc_peer), status);
                return -EIO;
@@ -396,7 +405,7 @@ brw_bulk_ready (srpc_server_rpc_t *rpc, int status)
                __swab64s(&magic);
 
        if (brw_check_bulk(rpc->srpc_bulk, reqst->brw_flags, magic) != 0) {
-               CERROR ("Bulk data from %s is corrupted!\n",
+               CERROR("Bulk data from %s is corrupted!\n",
                        libcfs_id2str(rpc->srpc_peer));
                reply->brw_status = EBADMSG;
        }
@@ -415,10 +424,10 @@ brw_server_handle(struct srpc_server_rpc *rpc)
        int               npg;
        int            rc;
 
-       LASSERT (sv->sv_id == SRPC_SERVICE_BRW);
+       LASSERT(sv->sv_id == SRPC_SERVICE_BRW);
 
        if (reqstmsg->msg_magic != SRPC_MSG_MAGIC) {
-               LASSERT (reqstmsg->msg_magic == __swab32(SRPC_MSG_MAGIC));
+               LASSERT(reqstmsg->msg_magic == __swab32(SRPC_MSG_MAGIC));
 
                __swab32s(&reqst->brw_rw);
                __swab32s(&reqst->brw_len);
@@ -426,7 +435,7 @@ brw_server_handle(struct srpc_server_rpc *rpc)
                __swab64s(&reqst->brw_rpyid);
                __swab64s(&reqst->brw_bulkid);
        }
-       LASSERT (reqstmsg->msg_type == (__u32)srpc_service2request(sv->sv_id));
+       LASSERT(reqstmsg->msg_type == (__u32)srpc_service2request(sv->sv_id));
 
        reply->brw_status = 0;
        rpc->srpc_done = brw_server_rpc_done;
index cbce662b987bdce0ce2f6ac4b84e7490a5f68f33..9a52f25b72e90931053c7bf642789797ca522325 100644 (file)
@@ -75,7 +75,7 @@ lstcon_rpc_done(srpc_client_rpc_t *rpc)
 
        if (crpc->crp_stamp == 0) {
                /* not aborted */
-               LASSERT (crpc->crp_status == 0);
+               LASSERT(crpc->crp_status == 0);
 
                crpc->crp_stamp  = cfs_time_current();
                crpc->crp_status = rpc->crpc_status;
@@ -153,7 +153,7 @@ lstcon_rpc_put(lstcon_rpc_t *crpc)
        srpc_bulk_t *bulk = &crpc->crp_rpc->crpc_bulk;
        int       i;
 
-       LASSERT (list_empty(&crpc->crp_link));
+       LASSERT(list_empty(&crpc->crp_link));
 
        for (i = 0; i < bulk->bk_niov; i++) {
                if (bulk->bk_iovs[i].kiov_page == NULL)
@@ -187,7 +187,7 @@ lstcon_rpc_post(lstcon_rpc_t *crpc)
 {
        lstcon_rpc_trans_t *trans = crpc->crp_trans;
 
-       LASSERT (trans != NULL);
+       LASSERT(trans != NULL);
 
        atomic_inc(&trans->tas_remaining);
        crpc->crp_posted = 1;
@@ -289,7 +289,7 @@ lstcon_rpc_trans_abort(lstcon_rpc_trans_t *trans, int error)
        lstcon_rpc_t      *crpc;
        lstcon_node_t     *nd;
 
-       list_for_each_entry (crpc, &trans->tas_rpcs_list, crp_link) {
+       list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
                rpc = crpc->crp_rpc;
 
                spin_lock(&rpc->crpc_lock);
@@ -330,7 +330,7 @@ lstcon_rpc_trans_check(lstcon_rpc_trans_t *trans)
            !list_empty(&trans->tas_olink)) /* Not an end session RPC */
                return 1;
 
-       return (atomic_read(&trans->tas_remaining) == 0) ? 1: 0;
+       return (atomic_read(&trans->tas_remaining) == 0) ? 1 : 0;
 }
 
 int
@@ -349,8 +349,8 @@ lstcon_rpc_trans_postwait(lstcon_rpc_trans_t *trans, int timeout)
               lstcon_rpc_trans_name(trans->tas_opc));
 
        /* post all requests */
-       list_for_each_entry (crpc, &trans->tas_rpcs_list, crp_link) {
-               LASSERT (!crpc->crp_posted);
+       list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
+               LASSERT(!crpc->crp_posted);
 
                lstcon_rpc_post(crpc);
        }
@@ -390,8 +390,8 @@ lstcon_rpc_get_reply(lstcon_rpc_t *crpc, srpc_msg_t **msgpp)
        srpc_client_rpc_t    *rpc = crpc->crp_rpc;
        srpc_generic_reply_t *rep;
 
-       LASSERT (nd != NULL && rpc != NULL);
-       LASSERT (crpc->crp_stamp != 0);
+       LASSERT(nd != NULL && rpc != NULL);
+       LASSERT(crpc->crp_stamp != 0);
 
        if (crpc->crp_status != 0) {
                *msgpp = NULL;
@@ -427,14 +427,14 @@ lstcon_rpc_trans_stat(lstcon_rpc_trans_t *trans, lstcon_trans_stat_t *stat)
        srpc_msg_t      *rep;
        int             error;
 
-       LASSERT (stat != NULL);
+       LASSERT(stat != NULL);
 
        memset(stat, 0, sizeof(*stat));
 
        list_for_each_entry(crpc, &trans->tas_rpcs_list, crp_link) {
                lstcon_rpc_stat_total(stat, 1);
 
-               LASSERT (crpc->crp_stamp != 0);
+               LASSERT(crpc->crp_stamp != 0);
 
                error = lstcon_rpc_get_reply(crpc, &rep);
                if (error != 0) {
@@ -455,8 +455,7 @@ lstcon_rpc_trans_stat(lstcon_rpc_trans_t *trans, lstcon_trans_stat_t *stat)
                      lstcon_session_feats_check(trans->tas_features);
        }
 
-       CDEBUG(D_NET, "transaction %s : success %d, failure %d, total %d, "
-                     "RPC error(%d), Framework error(%d)\n",
+       CDEBUG(D_NET, "transaction %s : success %d, failure %d, total %d, RPC error(%d), Framework error(%d)\n",
               lstcon_rpc_trans_name(trans->tas_opc),
               lstcon_rpc_stat_success(stat, 0),
               lstcon_rpc_stat_failure(stat, 0),
@@ -482,7 +481,7 @@ lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
        struct timeval  tv;
        int                error;
 
-       LASSERT (head_up != NULL);
+       LASSERT(head_up != NULL);
 
        next = head_up;
 
@@ -498,7 +497,7 @@ lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
 
                ent = list_entry(next, lstcon_rpc_ent_t, rpe_link);
 
-               LASSERT (crpc->crp_stamp != 0);
+               LASSERT(crpc->crp_stamp != 0);
 
                error = lstcon_rpc_get_reply(crpc, &msg);
 
@@ -532,7 +531,9 @@ lstcon_rpc_trans_interpreter(lstcon_rpc_trans_t *trans,
                if (readent == NULL)
                        continue;
 
-               if ((error = readent(trans->tas_opc, msg, ent)) != 0)
+               error = readent(trans->tas_opc, msg, ent);
+
+               if (error != 0)
                        return error;
        }
 
@@ -568,19 +569,19 @@ lstcon_rpc_trans_destroy(lstcon_rpc_trans_t *trans)
                 * user wait for them, just abandon them, they will be recycled
                 * in callback */
 
-               LASSERT (crpc->crp_status != 0);
+               LASSERT(crpc->crp_status != 0);
 
                crpc->crp_node  = NULL;
                crpc->crp_trans = NULL;
                list_del_init(&crpc->crp_link);
-               count ++;
+               count++;
 
                spin_unlock(&rpc->crpc_lock);
 
                atomic_dec(&trans->tas_remaining);
        }
 
-       LASSERT (atomic_read(&trans->tas_remaining) == 0);
+       LASSERT(atomic_read(&trans->tas_remaining) == 0);
 
        list_del(&trans->tas_link);
        if (!list_empty(&trans->tas_olink))
@@ -669,14 +670,14 @@ lstcon_batrpc_prep(lstcon_node_t *nd, int transop, unsigned feats,
        brq->bar_bid     = tsb->tsb_id;
        brq->bar_testidx = tsb->tsb_index;
        brq->bar_opc     = transop == LST_TRANS_TSBRUN ? SRPC_BATCH_OPC_RUN :
-                          (transop == LST_TRANS_TSBSTOP ? SRPC_BATCH_OPC_STOP:
+                          (transop == LST_TRANS_TSBSTOP ? SRPC_BATCH_OPC_STOP :
                            SRPC_BATCH_OPC_QUERY);
 
        if (transop != LST_TRANS_TSBRUN &&
            transop != LST_TRANS_TSBSTOP)
                return 0;
 
-       LASSERT (tsb->tsb_index == 0);
+       LASSERT(tsb->tsb_index == 0);
 
        batch = (lstcon_batch_t *)tsb;
        brq->bar_arg = batch->bat_arg;
@@ -710,7 +711,7 @@ lstcon_next_id(int idx, int nkiov, lnet_kiov_t *kiov)
 
        i = idx / SFW_ID_PER_PAGE;
 
-       LASSERT (i < nkiov);
+       LASSERT(i < nkiov);
 
        pid = (lnet_process_id_packed_t *)page_address(kiov[i].kiov_page);
 
@@ -728,9 +729,9 @@ lstcon_dstnodes_prep(lstcon_group_t *grp, int idx,
        int                    end;
        int                    i = 0;
 
-       LASSERT (dist >= 1);
-       LASSERT (span >= 1);
-       LASSERT (grp->grp_nnode >= 1);
+       LASSERT(dist >= 1);
+       LASSERT(span >= 1);
+       LASSERT(grp->grp_nnode >= 1);
 
        if (span > grp->grp_nnode)
                return -EINVAL;
@@ -741,11 +742,11 @@ lstcon_dstnodes_prep(lstcon_group_t *grp, int idx,
        list_for_each_entry(ndl, &grp->grp_ndl_list, ndl_link) {
                nd = ndl->ndl_node;
                if (i < start) {
-                       i ++;
+                       i++;
                        continue;
                }
 
-               if (i > (end >= start ? end: grp->grp_nnode))
+               if (i > (end >= start ? end : grp->grp_nnode))
                        break;
 
                pid = lstcon_next_id((i - start), nkiov, kiov);
@@ -866,7 +867,7 @@ lstcon_testrpc_prep(lstcon_node_t *nd, int transop, unsigned feats,
 
                bulk->bk_sink = 0;
 
-               LASSERT (transop == LST_TRANS_TSBCLIADD);
+               LASSERT(transop == LST_TRANS_TSBCLIADD);
 
                rc = lstcon_dstnodes_prep(test->tes_dst_grp,
                                          test->tes_cliidx++,
@@ -942,8 +943,7 @@ lstcon_sesnew_stat_reply(lstcon_rpc_trans_t *trans,
        }
 
        if (reply->msg_ses_feats != trans->tas_features) {
-               CNETERR("Framework features %x from %s is different with "
-                       "features on this transaction: %x\n",
+               CNETERR("Framework features %x from %s is different with features on this transaction: %x\n",
                         reply->msg_ses_feats, libcfs_nid2str(nd->nd_id.nid),
                         trans->tas_features);
                status = mksn_rep->mksn_status = EPROTO;
@@ -1107,8 +1107,8 @@ lstcon_rpc_trans_ndlist(struct list_head *ndlist,
                        continue;
 
                if (rc < 0) {
-                       CDEBUG(D_NET, "Condition error while creating RPC "
-                                     " for transaction %d: %d\n", transop, rc);
+                       CDEBUG(D_NET, "Condition error while creating RPC for transaction %d: %d\n",
+                                       transop, rc);
                        break;
                }
 
@@ -1193,7 +1193,7 @@ lstcon_rpc_pinger(void *arg)
 
        trans = console_session.ses_ping;
 
-       LASSERT (trans != NULL);
+       LASSERT(trans != NULL);
 
        list_for_each_entry(ndl, &console_session.ses_ndl_list, ndl_link) {
                nd = ndl->ndl_node;
@@ -1219,8 +1219,8 @@ lstcon_rpc_pinger(void *arg)
                crpc = &nd->nd_ping;
 
                if (crpc->crp_rpc != NULL) {
-                       LASSERT (crpc->crp_trans == trans);
-                       LASSERT (!list_empty(&crpc->crp_link));
+                       LASSERT(crpc->crp_trans == trans);
+                       LASSERT(!list_empty(&crpc->crp_link));
 
                        spin_lock(&crpc->crp_rpc->crpc_lock);
 
@@ -1264,7 +1264,7 @@ lstcon_rpc_pinger(void *arg)
                lstcon_rpc_trans_addreq(trans, crpc);
                lstcon_rpc_post(crpc);
 
-               count ++;
+               count++;
        }
 
        if (console_session.ses_expired) {
@@ -1286,8 +1286,8 @@ lstcon_rpc_pinger_start(void)
        stt_timer_t    *ptimer;
        int          rc;
 
-       LASSERT (list_empty(&console_session.ses_rpc_freelist));
-       LASSERT (atomic_read(&console_session.ses_rpc_counter) == 0);
+       LASSERT(list_empty(&console_session.ses_rpc_freelist));
+       LASSERT(atomic_read(&console_session.ses_rpc_counter) == 0);
 
        rc = lstcon_rpc_trans_prep(NULL, LST_TRANS_SESPING,
                                   &console_session.ses_ping);
@@ -1307,7 +1307,7 @@ lstcon_rpc_pinger_start(void)
 void
 lstcon_rpc_pinger_stop(void)
 {
-       LASSERT (console_session.ses_shutdown);
+       LASSERT(console_session.ses_shutdown);
 
        stt_del_timer(&console_session.ses_ping_timer);
 
@@ -1330,7 +1330,7 @@ lstcon_rpc_cleanup_wait(void)
 
        /* Called with hold of global mutex */
 
-       LASSERT (console_session.ses_shutdown);
+       LASSERT(console_session.ses_shutdown);
 
        while (!list_empty(&console_session.ses_trans_list)) {
                list_for_each(pacer, &console_session.ses_trans_list) {
@@ -1345,8 +1345,7 @@ lstcon_rpc_cleanup_wait(void)
 
                mutex_unlock(&console_session.ses_mutex);
 
-               CWARN("Session is shutting down, "
-                     "waiting for termination of transactions\n");
+               CWARN("Session is shutting down, waiting for termination of transactions\n");
                cfs_pause(cfs_time_seconds(1));
 
                mutex_lock(&console_session.ses_mutex);
@@ -1356,8 +1355,7 @@ lstcon_rpc_cleanup_wait(void)
 
        lst_wait_until((atomic_read(&console_session.ses_rpc_counter) == 0),
                       console_session.ses_rpc_lock,
-                      "Network is not accessible or target is down, "
-                      "waiting for %d console RPCs to being recycled\n",
+                      "Network is not accessible or target is down, waiting for %d console RPCs to being recycled\n",
                       atomic_read(&console_session.ses_rpc_counter));
 
        list_add(&zlist, &console_session.ses_rpc_freelist);
@@ -1392,6 +1390,6 @@ lstcon_rpc_module_init(void)
 void
 lstcon_rpc_module_fini(void)
 {
-       LASSERT (list_empty(&console_session.ses_rpc_freelist));
-       LASSERT (atomic_read(&console_session.ses_rpc_counter) == 0);
+       LASSERT(list_empty(&console_session.ses_rpc_freelist));
+       LASSERT(atomic_read(&console_session.ses_rpc_counter) == 0);
 }
index 09e4700af6405b5429dd2aa5c41f5485b29cd8f5..f1152e4fbcc41972fd115517348344d2122b9aa2 100644 (file)
@@ -797,7 +797,7 @@ lstcon_group_info(char *name, lstcon_ndlist_ent_t *gents_p,
                return rc;
        }
 
-       if (dents_up != 0) {
+       if (dents_up) {
                /* verbose query */
                rc = lstcon_nodes_getent(&grp->grp_ndl_list,
                                         index_p, count_p, dents_up);
index 3bf4afb42ffe3c1bc03ea67bedbef87467b015d1..82fd363679cb94d9e5a2a0e1d28e8cdce8c048b3 100644 (file)
@@ -74,14 +74,14 @@ stt_add_timer(stt_timer_t *timer)
 
        spin_lock(&stt_data.stt_lock);
 
-       LASSERT (stt_data.stt_nthreads > 0);
-       LASSERT (!stt_data.stt_shuttingdown);
-       LASSERT (timer->stt_func != NULL);
-       LASSERT (list_empty(&timer->stt_list));
-       LASSERT (cfs_time_after(timer->stt_expires, cfs_time_current_sec()));
+       LASSERT(stt_data.stt_nthreads > 0);
+       LASSERT(!stt_data.stt_shuttingdown);
+       LASSERT(timer->stt_func != NULL);
+       LASSERT(list_empty(&timer->stt_list));
+       LASSERT(cfs_time_after(timer->stt_expires, cfs_time_current_sec()));
 
        /* a simple insertion sort */
-       list_for_each_prev (pos, STTIMER_SLOT(timer->stt_expires)) {
+       list_for_each_prev(pos, STTIMER_SLOT(timer->stt_expires)) {
                stt_timer_t *old = list_entry(pos, stt_timer_t, stt_list);
 
                if (cfs_time_aftereq(timer->stt_expires, old->stt_expires))
@@ -102,14 +102,14 @@ stt_add_timer(stt_timer_t *timer)
  * another CPU.
  */
 int
-stt_del_timer (stt_timer_t *timer)
+stt_del_timer(stt_timer_t *timer)
 {
        int ret = 0;
 
        spin_lock(&stt_data.stt_lock);
 
-       LASSERT (stt_data.stt_nthreads > 0);
-       LASSERT (!stt_data.stt_shuttingdown);
+       LASSERT(stt_data.stt_nthreads > 0);
+       LASSERT(!stt_data.stt_shuttingdown);
 
        if (!list_empty(&timer->stt_list)) {
                ret = 1;
@@ -122,7 +122,7 @@ stt_del_timer (stt_timer_t *timer)
 
 /* called with stt_data.stt_lock held */
 int
-stt_expire_list (struct list_head *slot, cfs_time_t now)
+stt_expire_list(struct list_head *slot, cfs_time_t now)
 {
        int       expired = 0;
        stt_timer_t *timer;
@@ -146,7 +146,7 @@ stt_expire_list (struct list_head *slot, cfs_time_t now)
 }
 
 int
-stt_check_timers (cfs_time_t *last)
+stt_check_timers(cfs_time_t *last)
 {
        int     expired = 0;
        cfs_time_t now;
@@ -169,7 +169,7 @@ stt_check_timers (cfs_time_t *last)
 
 
 int
-stt_timer_main (void *arg)
+stt_timer_main(void *arg)
 {
        int rc = 0;
        UNUSED(arg);
@@ -193,7 +193,7 @@ stt_timer_main (void *arg)
 }
 
 int
-stt_start_timer_thread (void)
+stt_start_timer_thread(void)
 {
        struct task_struct *task;
 
@@ -211,7 +211,7 @@ stt_start_timer_thread (void)
 
 
 int
-stt_startup (void)
+stt_startup(void)
 {
        int rc = 0;
        int i;
@@ -227,20 +227,20 @@ stt_startup (void)
        init_waitqueue_head(&stt_data.stt_waitq);
        rc = stt_start_timer_thread();
        if (rc != 0)
-               CERROR ("Can't spawn timer thread: %d\n", rc);
+               CERROR("Can't spawn timer thread: %d\n", rc);
 
        return rc;
 }
 
 void
-stt_shutdown (void)
+stt_shutdown(void)
 {
        int i;
 
        spin_lock(&stt_data.stt_lock);
 
        for (i = 0; i < STTIMER_NSLOTS; i++)
-               LASSERT (list_empty(&stt_data.stt_hash[i]));
+               LASSERT(list_empty(&stt_data.stt_hash[i]));
 
        stt_data.stt_shuttingdown = 1;
 
index 2156a44d07409c0501cba726ccb33ee99d1d9c92..93d59b6a60daa6cb1916281016421ce0c84fbf4a 100644 (file)
@@ -16,7 +16,7 @@ config LUSTRE_FS
          this file system support as a module, choose M here: the module will
          be called lustre.
 
-         To mount Lustre file systems , you also need to install the user space
+         To mount Lustre file systems, you also need to install the user space
          mount.lustre and other user space commands which can be found in the
          lustre-client package, available from
          http://downloads.whamcloud.com/public/lustre/
index 25099cbe37eb7bf9a7b95911322cde1400407b5c..45315101848cba68799853291361930a6bc0be44 100644 (file)
@@ -267,7 +267,7 @@ void fld_cache_punch_hole(struct fld_cache *cache,
        const seqno_t new_end  = range->lsr_end;
        struct fld_cache_entry *fldt;
 
-       OBD_ALLOC_GFP(fldt, sizeof *fldt, GFP_ATOMIC);
+       OBD_ALLOC_GFP(fldt, sizeof(*fldt), GFP_ATOMIC);
        if (!fldt) {
                OBD_FREE_PTR(f_new);
                /* overlap is not allowed, so dont mess up list. */
index edb40afe66f122be83e83e4b871064a96dc8e30a..c485206fc6c2207f1933a1cc4b19598c35a281bf 100644 (file)
@@ -3096,13 +3096,13 @@ struct cl_io *cl_io_top(struct cl_io *io);
 void cl_io_print(const struct lu_env *env, void *cookie,
                 lu_printer_t printer, const struct cl_io *io);
 
-#define CL_IO_SLICE_CLEAN(foo_io, base)                                 \
-do {                                                               \
-       typeof(foo_io) __foo_io = (foo_io);                          \
+#define CL_IO_SLICE_CLEAN(foo_io, base)                                        \
+do {                                                                   \
+       typeof(foo_io) __foo_io = (foo_io);                             \
                                                                        \
-       CLASSERT(offsetof(typeof(*__foo_io), base) == 0);              \
-       memset(&__foo_io->base + 1, 0,                            \
-              (sizeof *__foo_io) - sizeof __foo_io->base);          \
+       CLASSERT(offsetof(typeof(*__foo_io), base) == 0);               \
+       memset(&__foo_io->base + 1, 0,                                  \
+              sizeof(*__foo_io) - sizeof(__foo_io->base));             \
 } while (0)
 
 /** @} cl_io */
index 9d4011f2908b91752e73c05143dd2bc718118734..27316f7b7a70013ccf765d76686db595e77bf4bd 100644 (file)
@@ -388,8 +388,8 @@ __u16 ll_dirent_type_get(struct lu_dirent *ent);
 __u64 cl_fid_build_ino(const struct lu_fid *fid, int api32);
 __u32 cl_fid_build_gen(const struct lu_fid *fid);
 
-# define CLOBINVRNT(env, clob, expr)                               \
-       ((void)sizeof(env), (void)sizeof(clob), (void)sizeof !!(expr))
+# define CLOBINVRNT(env, clob, expr)                                   \
+       ((void)sizeof(env), (void)sizeof(clob), (void)sizeof(!!(expr)))
 
 int cl_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp);
 int cl_ocd_update(struct obd_device *host,
index 9243dfab43d393f360a0f78c7dd7b8677455676f..359c6c1ba68d013589b92765c3bb40e48044b07b 100644 (file)
@@ -232,9 +232,6 @@ static inline int ll_namei_to_lookup_intent_flag(int flag)
        return flag;
 }
 
-# define ll_mrf_ret void
-# define LL_MRF_RETURN(rc)
-
 #include <linux/fs.h>
 
 # define ll_umode_t    umode_t
index 984235ccd3a5fb92a687e3ca538f4a339afc53bd..5ca18d01601429e5452bee9b1a839d7ce1df4bd3 100644 (file)
@@ -831,9 +831,10 @@ static inline void lu_igif_build(struct lu_fid *fid, __u32 ino, __u32 gen)
 static inline void fid_cpu_to_le(struct lu_fid *dst, const struct lu_fid *src)
 {
        /* check that all fields are converted */
-       CLASSERT(sizeof *src ==
-                sizeof fid_seq(src) +
-                sizeof fid_oid(src) + sizeof fid_ver(src));
+       CLASSERT(sizeof(*src) ==
+                sizeof(fid_seq(src)) +
+                sizeof(fid_oid(src)) +
+                sizeof(fid_ver(src)));
        dst->f_seq = cpu_to_le64(fid_seq(src));
        dst->f_oid = cpu_to_le32(fid_oid(src));
        dst->f_ver = cpu_to_le32(fid_ver(src));
@@ -842,9 +843,10 @@ static inline void fid_cpu_to_le(struct lu_fid *dst, const struct lu_fid *src)
 static inline void fid_le_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
 {
        /* check that all fields are converted */
-       CLASSERT(sizeof *src ==
-                sizeof fid_seq(src) +
-                sizeof fid_oid(src) + sizeof fid_ver(src));
+       CLASSERT(sizeof(*src) ==
+                sizeof(fid_seq(src)) +
+                sizeof(fid_oid(src)) +
+                sizeof(fid_ver(src)));
        dst->f_seq = le64_to_cpu(fid_seq(src));
        dst->f_oid = le32_to_cpu(fid_oid(src));
        dst->f_ver = le32_to_cpu(fid_ver(src));
@@ -853,9 +855,10 @@ static inline void fid_le_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
 static inline void fid_cpu_to_be(struct lu_fid *dst, const struct lu_fid *src)
 {
        /* check that all fields are converted */
-       CLASSERT(sizeof *src ==
-                sizeof fid_seq(src) +
-                sizeof fid_oid(src) + sizeof fid_ver(src));
+       CLASSERT(sizeof(*src) ==
+                sizeof(fid_seq(src)) +
+                sizeof(fid_oid(src)) +
+                sizeof(fid_ver(src)));
        dst->f_seq = cpu_to_be64(fid_seq(src));
        dst->f_oid = cpu_to_be32(fid_oid(src));
        dst->f_ver = cpu_to_be32(fid_ver(src));
@@ -864,9 +867,10 @@ static inline void fid_cpu_to_be(struct lu_fid *dst, const struct lu_fid *src)
 static inline void fid_be_to_cpu(struct lu_fid *dst, const struct lu_fid *src)
 {
        /* check that all fields are converted */
-       CLASSERT(sizeof *src ==
-                sizeof fid_seq(src) +
-                sizeof fid_oid(src) + sizeof fid_ver(src));
+       CLASSERT(sizeof(*src) ==
+                sizeof(fid_seq(src)) +
+                sizeof(fid_oid(src)) +
+                sizeof(fid_ver(src)));
        dst->f_seq = be64_to_cpu(fid_seq(src));
        dst->f_oid = be32_to_cpu(fid_oid(src));
        dst->f_ver = be32_to_cpu(fid_ver(src));
@@ -891,9 +895,11 @@ extern void lustre_swab_lu_seq_range(struct lu_seq_range *range);
 static inline int lu_fid_eq(const struct lu_fid *f0, const struct lu_fid *f1)
 {
        /* Check that there is no alignment padding. */
-       CLASSERT(sizeof *f0 ==
-                sizeof f0->f_seq + sizeof f0->f_oid + sizeof f0->f_ver);
-       return memcmp(f0, f1, sizeof *f0) == 0;
+       CLASSERT(sizeof(*f0) ==
+                sizeof(f0->f_seq) +
+                sizeof(f0->f_oid) +
+                sizeof(f0->f_ver));
+       return memcmp(f0, f1, sizeof(*f0)) == 0;
 }
 
 #define __diff_normalize(val0, val1)                       \
@@ -1638,8 +1644,10 @@ static inline void lmm_oi_cpu_to_le(struct ost_id *dst_oi,
 
 /* extern void lustre_swab_lov_mds_md(struct lov_mds_md *llm); */
 
-#define MAX_MD_SIZE (sizeof(struct lov_mds_md) + 4 * sizeof(struct lov_ost_data))
-#define MIN_MD_SIZE (sizeof(struct lov_mds_md) + 1 * sizeof(struct lov_ost_data))
+#define MAX_MD_SIZE                                                    \
+       (sizeof(struct lov_mds_md) + 4 * sizeof(struct lov_ost_data))
+#define MIN_MD_SIZE                                                    \
+       (sizeof(struct lov_mds_md) + 1 * sizeof(struct lov_ost_data))
 
 #define XATTR_NAME_ACL_ACCESS   "system.posix_acl_access"
 #define XATTR_NAME_ACL_DEFAULT  "system.posix_acl_default"
index d9d5814e318d9e8105195d7bbc17db5e043c6815..ff119532dafb352b7a6f7f57bbba59b5791a14ca 100644 (file)
@@ -590,7 +590,7 @@ fid_build_pdo_res_name(const struct lu_fid *fid, unsigned int hash,
 static inline void ostid_build_res_name(struct ost_id *oi,
                                        struct ldlm_res_id *name)
 {
-       memset(name, 0, sizeof *name);
+       memset(name, 0, sizeof(*name));
        if (fid_seq_is_mdt0(ostid_seq(oi))) {
                name->name[LUSTRE_RES_ID_SEQ_OFF] = ostid_id(oi);
                name->name[LUSTRE_RES_ID_VER_OID_OFF] = ostid_seq(oi);
index a6122559d55d20fc01680414e7fb637f54fc16bb..4fd4af9f29c9c6931857d08057fcae0a334dae48 100644 (file)
@@ -177,7 +177,7 @@ static inline int lov_stripe_md_cmp(struct lov_stripe_md *m1,
         * ->lsm_wire contains padding, but it should be zeroed out during
         * allocation.
         */
-       return memcmp(&m1->lsm_wire, &m2->lsm_wire, sizeof m1->lsm_wire);
+       return memcmp(&m1->lsm_wire, &m2->lsm_wire, sizeof(m1->lsm_wire));
 }
 
 static inline int lov_lum_lsm_cmp(struct lov_user_md *lum,
index 03e6133ef50fc74fb969dc2a6203196675163c05..9697e7faff2fddbb62e484121e7186adcab4077c 100644 (file)
@@ -633,8 +633,8 @@ do {                                                                              \
 
 #define OBD_ALLOC(ptr, size) OBD_ALLOC_GFP(ptr, size, __GFP_IO)
 #define OBD_ALLOC_WAIT(ptr, size) OBD_ALLOC_GFP(ptr, size, GFP_IOFS)
-#define OBD_ALLOC_PTR(ptr) OBD_ALLOC(ptr, sizeof *(ptr))
-#define OBD_ALLOC_PTR_WAIT(ptr) OBD_ALLOC_WAIT(ptr, sizeof *(ptr))
+#define OBD_ALLOC_PTR(ptr) OBD_ALLOC(ptr, sizeof(*(ptr)))
+#define OBD_ALLOC_PTR_WAIT(ptr) OBD_ALLOC_WAIT(ptr, sizeof(*(ptr)))
 
 #define OBD_CPT_ALLOC_GFP(ptr, cptab, cpt, size, gfp_mask)                   \
        __OBD_MALLOC_VERBOSE(ptr, cptab, cpt, size, gfp_mask)
@@ -643,7 +643,7 @@ do {                                                                              \
        OBD_CPT_ALLOC_GFP(ptr, cptab, cpt, size, __GFP_IO)
 
 #define OBD_CPT_ALLOC_PTR(ptr, cptab, cpt)                                   \
-       OBD_CPT_ALLOC(ptr, cptab, cpt, sizeof *(ptr))
+       OBD_CPT_ALLOC(ptr, cptab, cpt, sizeof(*(ptr)))
 
 # define __OBD_VMALLOC_VEROBSE(ptr, cptab, cpt, size)                        \
 do {                                                                         \
@@ -773,7 +773,7 @@ do {                                                                              \
 #define OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, size, flags)           \
        __OBD_SLAB_ALLOC_VERBOSE(ptr, slab, cptab, cpt, size, flags)
 
-#define OBD_FREE_PTR(ptr) OBD_FREE(ptr, sizeof *(ptr))
+#define OBD_FREE_PTR(ptr) OBD_FREE(ptr, sizeof(*(ptr)))
 
 #define OBD_SLAB_FREE(ptr, slab, size)                                 \
 do {                                                                     \
@@ -789,19 +789,19 @@ do {                                                                        \
        OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, size, __GFP_IO)
 
 #define OBD_SLAB_ALLOC_PTR(ptr, slab)                                        \
-       OBD_SLAB_ALLOC(ptr, slab, sizeof *(ptr))
+       OBD_SLAB_ALLOC(ptr, slab, sizeof(*(ptr)))
 
 #define OBD_SLAB_CPT_ALLOC_PTR(ptr, slab, cptab, cpt)                        \
-       OBD_SLAB_CPT_ALLOC(ptr, slab, cptab, cpt, sizeof *(ptr))
+       OBD_SLAB_CPT_ALLOC(ptr, slab, cptab, cpt, sizeof(*(ptr)))
 
 #define OBD_SLAB_ALLOC_PTR_GFP(ptr, slab, flags)                             \
-       OBD_SLAB_ALLOC_GFP(ptr, slab, sizeof *(ptr), flags)
+       OBD_SLAB_ALLOC_GFP(ptr, slab, sizeof(*(ptr)), flags)
 
 #define OBD_SLAB_CPT_ALLOC_PTR_GFP(ptr, slab, cptab, cpt, flags)                     \
-       OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, sizeof *(ptr), flags)
+       OBD_SLAB_CPT_ALLOC_GFP(ptr, slab, cptab, cpt, sizeof(*(ptr)), flags)
 
 #define OBD_SLAB_FREE_PTR(ptr, slab)                                         \
-       OBD_SLAB_FREE((ptr), (slab), sizeof *(ptr))
+       OBD_SLAB_FREE((ptr), (slab), sizeof(*(ptr)))
 
 #define KEY_IS(str) \
        (keylen >= (sizeof(str)-1) && memcmp(key, str, (sizeof(str)-1)) == 0)
index 8ff38c64b7a1fcf5e28c4f148f9b7d869464bd1a..e60c04d5393abaf6bf51ac3834adaf274d432d45 100644 (file)
@@ -701,7 +701,7 @@ int ccc_io_one_lock_index(const struct lu_env *env, struct cl_io *io,
 
        CDEBUG(D_VFSTRACE, "lock: %d [%lu, %lu]\n", mode, start, end);
 
-       memset(&cio->cui_link, 0, sizeof cio->cui_link);
+       memset(&cio->cui_link, 0, sizeof(cio->cui_link));
 
        if (cio->cui_fd && (cio->cui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
                descr->cld_mode = CLM_GROUP;
index 6133b3f347182f1d202f412ce4b10556fc1df3d2..027617f5083fb81343c541042167f0d034a81752 100644 (file)
@@ -529,7 +529,7 @@ int ldlm_lock_change_resource(struct ldlm_namespace *ns, struct ldlm_lock *lock,
                lock_res_nested(oldres, LRT_NEW);
        }
        LASSERT(memcmp(new_resid, &oldres->lr_name,
-                      sizeof oldres->lr_name) != 0);
+                      sizeof(oldres->lr_name)) != 0);
        lock->l_resource = newres;
        unlock_res(oldres);
        unlock_res_and_lock(lock);
index 208751a154b3c6de28194b30b937f48ddee54653..8d3dd6dad9b7dded72132d1dbd84fd17c04a6f9c 100644 (file)
@@ -1115,7 +1115,7 @@ ldlm_resource_get(struct ldlm_namespace *ns, struct ldlm_resource *parent,
                lu_ref_fini(&res->lr_reference);
                /* We have taken lr_lvb_mutex. Drop it. */
                mutex_unlock(&res->lr_lvb_mutex);
-               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res);
+               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof(*res));
 
                res = hlist_entry(hnode, struct ldlm_resource, lr_hash);
                /* Synchronize with regard to resource creation. */
@@ -1226,7 +1226,7 @@ int ldlm_resource_putref(struct ldlm_resource *res)
                cfs_hash_bd_unlock(ns->ns_rs_hash, &bd, 1);
                if (ns->ns_lvbo && ns->ns_lvbo->lvbo_free)
                        ns->ns_lvbo->lvbo_free(res);
-               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res);
+               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof(*res));
                return 1;
        }
        return 0;
@@ -1256,7 +1256,7 @@ int ldlm_resource_putref_locked(struct ldlm_resource *res)
                 */
                if (ns->ns_lvbo && ns->ns_lvbo->lvbo_free)
                        ns->ns_lvbo->lvbo_free(res);
-               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof *res);
+               OBD_SLAB_FREE(res, ldlm_resource_slab, sizeof(*res));
 
                cfs_hash_bd_lock(ns->ns_rs_hash, &bd, 1);
                return 1;
index 0dd12c8c91b6126c0c790ef8932e033dcdc0d468..b0b8e3f81d5106d9c94230829798f967e21a80d3 100644 (file)
@@ -119,25 +119,25 @@ CFS_MODULE_PARM(warn_on_depth, "i", uint, 0644,
 struct cfs_wi_sched *cfs_sched_rehash;
 
 static inline void
-cfs_hash_nl_lock(cfs_hash_lock_t *lock, int exclusive) {}
+cfs_hash_nl_lock(union cfs_hash_lock *lock, int exclusive) {}
 
 static inline void
-cfs_hash_nl_unlock(cfs_hash_lock_t *lock, int exclusive) {}
+cfs_hash_nl_unlock(union cfs_hash_lock *lock, int exclusive) {}
 
 static inline void
-cfs_hash_spin_lock(cfs_hash_lock_t *lock, int exclusive)
+cfs_hash_spin_lock(union cfs_hash_lock *lock, int exclusive)
 {
        spin_lock(&lock->spin);
 }
 
 static inline void
-cfs_hash_spin_unlock(cfs_hash_lock_t *lock, int exclusive)
+cfs_hash_spin_unlock(union cfs_hash_lock *lock, int exclusive)
 {
        spin_unlock(&lock->spin);
 }
 
 static inline void
-cfs_hash_rw_lock(cfs_hash_lock_t *lock, int exclusive)
+cfs_hash_rw_lock(union cfs_hash_lock *lock, int exclusive)
 {
        if (!exclusive)
                read_lock(&lock->rw);
@@ -146,7 +146,7 @@ cfs_hash_rw_lock(cfs_hash_lock_t *lock, int exclusive)
 }
 
 static inline void
-cfs_hash_rw_unlock(cfs_hash_lock_t *lock, int exclusive)
+cfs_hash_rw_unlock(union cfs_hash_lock *lock, int exclusive)
 {
        if (!exclusive)
                read_unlock(&lock->rw);
@@ -1965,7 +1965,7 @@ cfs_hash_rehash_worker(cfs_workitem_t *wi)
        if (bkts != NULL)
                cfs_hash_buckets_free(bkts, bsize, new_size, old_size);
        if (rc != 0)
-               CDEBUG(D_INFO, "early quit of of rehashing: %d\n", rc);
+               CDEBUG(D_INFO, "early quit of rehashing: %d\n", rc);
        /* return 1 only if cfs_wi_exit is called */
        return rc == -ESRCH;
 }
index ea9e9490031fc81573e7a37f5fe6ca00b3723652..0bf8e5d87f1ad483035a3f0f93813530da56edc6 100644 (file)
@@ -167,7 +167,7 @@ static int cfs_access_process_vm(struct task_struct *tsk, unsigned long addr,
                return 0;
 
        down_read(&mm->mmap_sem);
-       /* ignore errors, just check how much was sucessfully transfered */
+       /* ignore errors, just check how much was successfully transferred */
        while (len) {
                int bytes, rc, offset;
                void *maddr;
@@ -227,8 +227,10 @@ int cfs_get_environ(const char *key, char *value, int *val_len)
         * which is already holding mmap_sem for writes.  If some other
         * thread gets the write lock in the meantime, this thread will
         * block, but at least it won't deadlock on itself.  LU-1735 */
-       if (down_read_trylock(&mm->mmap_sem) == 0)
+       if (down_read_trylock(&mm->mmap_sem) == 0) {
+               kfree(buffer);
                return -EDEADLK;
+       }
        up_read(&mm->mmap_sem);
 
        addr = mm->env_start;
index ab1e73168472445cc59b5b1e9c3165325684510b..cc565b1fb994397e8322d5dc7a66701c546e3c8d 100644 (file)
@@ -137,7 +137,7 @@ void libcfs_run_lbug_upcall(struct libcfs_debug_msg_data *msgdata)
        char *argv[6];
        char buf[32];
 
-       snprintf (buf, sizeof buf, "%d", msgdata->msg_line);
+       snprintf(buf, sizeof(buf), "%d", msgdata->msg_line);
 
        argv[1] = "LBUG";
        argv[2] = (char *)msgdata->msg_file;
index 69224d84bc4be87e00fa6ca12518612994800712..f87e9e516546f992998e6f8bb0ee07af09b1300f 100644 (file)
@@ -70,7 +70,7 @@ static unsigned int seed_y = 362436069;
  * cfs_rand - creates new seeds
  *
  * First it creates new seeds from the previous seeds. Then it generates a
- * new psuedo random number for use.
+ * new pseudo random number for use.
  *
  * Returns a pseudo-random 32-bit integer
  */
@@ -84,7 +84,7 @@ unsigned int cfs_rand(void)
 EXPORT_SYMBOL(cfs_rand);
 
 /**
- * cfs_srand - sets the inital seed
+ * cfs_srand - sets the initial seed
  * @seed1 : (seed_x) should have the most entropy in the low bits of the word
  * @seed2 : (seed_y) should have the most entropy in the high bits of the word
  *
index 09844be5eec4f09f9a4cdd24fb17127c9111019a..1f079034bd8f49aaed764925ef0dfc50c2ed65f2 100644 (file)
@@ -743,7 +743,7 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
 
        /* In the following we use the fact that LOV_USER_MAGIC_V1 and
         LOV_USER_MAGIC_V3 have the same initial fields so we do not
-        need the make the distiction between the 2 versions */
+        need to make the distinction between the 2 versions */
        if (set_default && mgc->u.cli.cl_mgc_mgsexp) {
                char *param = NULL;
                char *buf;
index bc534db1243169b8866f84b4875ed4852a66c963..fb85a58db058ec3f34cf80065e4b9cdb5e35c05f 100644 (file)
@@ -364,7 +364,7 @@ static int ll_intent_file_open(struct file *file, void *lmm,
           that case that lock is also ok */
        /* We can also get here if there was cached open handle in revalidate_it
         * but it disappeared while we were getting from there to ll_file_open.
-        * But this means this file was closed and immediatelly opened which
+        * But this means this file was closed and immediately opened which
         * makes a good candidate for using OPEN lock */
        /* If lmmsize & lmm are not 0, we are just setting stripe info
         * parameters. No need for the open lock */
@@ -2456,8 +2456,8 @@ static int ll_inode_revalidate_fini(struct inode *inode, int rc)
        if (rc == -ENOENT) {
                clear_nlink(inode);
                /* This path cannot be hit for regular files unless in
-                * case of obscure races, so no need to to validate
-                * size. */
+                * case of obscure races, so no need to validate size.
+                */
                if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
                        return 0;
        } else if (rc != 0) {
@@ -3011,7 +3011,7 @@ static int ll_layout_lock_set(struct lustre_handle *lockh, ldlm_mode_t mode,
 
        /* set layout to file. Unlikely this will fail as old layout was
         * surely eliminated */
-       memset(&conf, 0, sizeof conf);
+       memset(&conf, 0, sizeof(conf));
        conf.coc_opc = OBJECT_CONF_SET;
        conf.coc_inode = inode;
        conf.coc_lock = lock;
@@ -3034,7 +3034,7 @@ out:
                        ll_get_fsname(inode->i_sb, NULL, 0),
                        inode, PFID(&lli->lli_fid));
 
-               memset(&conf, 0, sizeof conf);
+               memset(&conf, 0, sizeof(conf));
                conf.coc_opc = OBJECT_CONF_WAIT;
                conf.coc_inode = inode;
                rc = ll_layout_conf(inode, &conf);
index 1f5825c87a79cdb861c2e21976f8f12dd988d721..e2996c46b2c02a2cb2602daeaff362b1ff128555 100644 (file)
@@ -159,7 +159,7 @@ void ll_ioepoch_close(struct inode *inode, struct md_op_data *op_data,
                }
                if (flags & LLIF_DONE_WRITING) {
                        /* Some pages are still dirty, it is early to send
-                        * DONE_WRITE. Wait untill all pages will be flushed
+                        * DONE_WRITE. Wait until all pages will be flushed
                         * and try DONE_WRITE again later. */
                        LASSERT(!(lli->lli_flags & LLIF_DONE_WRITING));
                        lli->lli_flags |= LLIF_DONE_WRITING;
index b868c2bd58d2a78787e2336d2c4b4a6259c3dd90..fd584ff7e2df0e22602347199a1ccfe02544ca41 100644 (file)
@@ -1973,10 +1973,10 @@ void ll_umount_begin(struct super_block *sb)
        OBD_ALLOC_PTR(ioc_data);
        if (ioc_data) {
                obd_iocontrol(IOC_OSC_SET_ACTIVE, sbi->ll_md_exp,
-                             sizeof *ioc_data, ioc_data, NULL);
+                             sizeof(*ioc_data), ioc_data, NULL);
 
                obd_iocontrol(IOC_OSC_SET_ACTIVE, sbi->ll_dt_exp,
-                             sizeof *ioc_data, ioc_data, NULL);
+                             sizeof(*ioc_data), ioc_data, NULL);
 
                OBD_FREE_PTR(ioc_data);
        }
index 2340458b8a04e6bcba5935e32ea9aad6a7e28861..e2421ea6135292aa37af132259356602770dcb67 100644 (file)
@@ -337,8 +337,7 @@ static unsigned int loop_get_bio(struct lloop_device *lo, struct bio **req)
        return count;
 }
 
-static ll_mrf_ret
-loop_make_request(struct request_queue *q, struct bio *old_bio)
+static void loop_make_request(struct request_queue *q, struct bio *old_bio)
 {
        struct lloop_device *lo = q->queuedata;
        int rw = bio_rw(old_bio);
@@ -366,10 +365,9 @@ loop_make_request(struct request_queue *q, struct bio *old_bio)
                goto err;
        }
        loop_add_bio(lo, old_bio);
-       LL_MRF_RETURN(0);
+       return;
 err:
        cfs_bio_io_error(old_bio, old_bio->bi_size);
-       LL_MRF_RETURN(0);
 }
 
 
index ae0dc441d1d9dd238ce0bfb4a5b37b46eeca607b..e9ba38a553cf3e62b90dfab2529efb8c491b1b72 100644 (file)
@@ -717,7 +717,7 @@ int ll_readahead(const struct lu_env *env, struct cl_io *io,
        lli = ll_i2info(inode);
        clob = lli->lli_clob;
 
-       memset(ria, 0, sizeof *ria);
+       memset(ria, 0, sizeof(*ria));
 
        cl_object_attr_lock(clob);
        ret = cl_object_attr_get(env, clob, attr);
index 96c29ad2fc8c5cd2992e766cba674bd4981fba06..7e3e0967993b5f6fecc7bfa965ef9a444cd0037f 100644 (file)
@@ -202,11 +202,8 @@ static inline int ll_get_user_pages(int rw, unsigned long user_addr,
 
        OBD_ALLOC_LARGE(*pages, *max_pages * sizeof(**pages));
        if (*pages) {
-               down_read(&current->mm->mmap_sem);
-               result = get_user_pages(current, current->mm, user_addr,
-                                       *max_pages, (rw == READ), 0, *pages,
-                                       NULL);
-               up_read(&current->mm->mmap_sem);
+               result = get_user_pages_fast(user_addr, *max_pages,
+                                            (rw == READ), *pages);
                if (unlikely(result <= 0))
                        OBD_FREE_LARGE(*pages, *max_pages * sizeof(**pages));
        }
index 8eaa38e91b9922084900660a08a6b15ecdb5cd08..f6b5f4b95f371de95f6ecaee5651c3c4e4201ecc 100644 (file)
@@ -647,7 +647,7 @@ static void ll_post_statahead(struct ll_statahead_info *sai)
                 */
                LASSERT(fid_is_zero(&minfo->mi_data.op_fid2));
 
-               /* XXX: No fid in reply, this is probaly cross-ref case.
+               /* XXX: No fid in reply, this is probably cross-ref case.
                 * SA can't handle it yet. */
                if (body->valid & OBD_MD_MDS)
                        GOTO(out, rc = -EAGAIN);
index 33d9ce68feddf8bb07fa70a56e7a81a7a76dff71..4276124d92e9837f7648835ddce7c55db5398a81 100644 (file)
@@ -564,50 +564,50 @@ extern struct kmem_cache *lovsub_req_kmem;
 
 extern struct kmem_cache *lov_lock_link_kmem;
 
-int   lov_object_init     (const struct lu_env *env, struct lu_object *obj,
+int   lov_object_init(const struct lu_env *env, struct lu_object *obj,
                           const struct lu_object_conf *conf);
-int   lovsub_object_init  (const struct lu_env *env, struct lu_object *obj,
+int   lovsub_object_init(const struct lu_env *env, struct lu_object *obj,
                           const struct lu_object_conf *conf);
-int   lov_lock_init       (const struct lu_env *env, struct cl_object *obj,
+int   lov_lock_init(const struct lu_env *env, struct cl_object *obj,
                           struct cl_lock *lock, const struct cl_io *io);
-int   lov_io_init       (const struct lu_env *env, struct cl_object *obj,
+int   lov_io_init(const struct lu_env *env, struct cl_object *obj,
                           struct cl_io *io);
-int   lovsub_lock_init    (const struct lu_env *env, struct cl_object *obj,
+int   lovsub_lock_init(const struct lu_env *env, struct cl_object *obj,
                           struct cl_lock *lock, const struct cl_io *io);
 
-int   lov_lock_init_raid0 (const struct lu_env *env, struct cl_object *obj,
+int   lov_lock_init_raid0(const struct lu_env *env, struct cl_object *obj,
                           struct cl_lock *lock, const struct cl_io *io);
-int   lov_lock_init_empty (const struct lu_env *env, struct cl_object *obj,
+int   lov_lock_init_empty(const struct lu_env *env, struct cl_object *obj,
                           struct cl_lock *lock, const struct cl_io *io);
-int   lov_io_init_raid0   (const struct lu_env *env, struct cl_object *obj,
+int   lov_io_init_raid0(const struct lu_env *env, struct cl_object *obj,
                           struct cl_io *io);
-int   lov_io_init_empty   (const struct lu_env *env, struct cl_object *obj,
+int   lov_io_init_empty(const struct lu_env *env, struct cl_object *obj,
                           struct cl_io *io);
 int   lov_io_init_released(const struct lu_env *env, struct cl_object *obj,
                           struct cl_io *io);
-void  lov_lock_unlink     (const struct lu_env *env, struct lov_lock_link *link,
+void  lov_lock_unlink(const struct lu_env *env, struct lov_lock_link *link,
                           struct lovsub_lock *sub);
 
 struct lov_io_sub *lov_sub_get(const struct lu_env *env, struct lov_io *lio,
                               int stripe);
-void  lov_sub_put           (struct lov_io_sub *sub);
-int   lov_sublock_modify  (const struct lu_env *env, struct lov_lock *lov,
+void  lov_sub_put(struct lov_io_sub *sub);
+int   lov_sublock_modify(const struct lu_env *env, struct lov_lock *lov,
                           struct lovsub_lock *sublock,
                           const struct cl_lock_descr *d, int idx);
 
 
-int   lov_page_init       (const struct lu_env *env, struct cl_object *ob,
+int   lov_page_init(const struct lu_env *env, struct cl_object *ob,
                           struct cl_page *page, struct page *vmpage);
-int   lovsub_page_init    (const struct lu_env *env, struct cl_object *ob,
+int   lovsub_page_init(const struct lu_env *env, struct cl_object *ob,
                           struct cl_page *page, struct page *vmpage);
 
-int   lov_page_init_empty (const struct lu_env *env,
+int   lov_page_init_empty(const struct lu_env *env,
                           struct cl_object *obj,
                           struct cl_page *page, struct page *vmpage);
-int   lov_page_init_raid0 (const struct lu_env *env,
+int   lov_page_init_raid0(const struct lu_env *env,
                           struct cl_object *obj,
                           struct cl_page *page, struct page *vmpage);
-struct lu_object *lov_object_alloc   (const struct lu_env *env,
+struct lu_object *lov_object_alloc(const struct lu_env *env,
                                      const struct lu_object_header *hdr,
                                      struct lu_device *dev);
 struct lu_object *lovsub_object_alloc(const struct lu_env *env,
@@ -617,7 +617,7 @@ struct lu_object *lovsub_object_alloc(const struct lu_env *env,
 struct lov_lock_link *lov_lock_link_find(const struct lu_env *env,
                                         struct lov_lock *lck,
                                         struct lovsub_lock *sub);
-struct lov_io_sub    *lov_page_subio    (const struct lu_env *env,
+struct lov_io_sub    *lov_page_subio(const struct lu_env *env,
                                         struct lov_io *lio,
                                         const struct cl_page_slice *slice);
 
index a4006ef46ad2a794eede17ee883fef91e6a259ea..1f33b04b0c38c06c02f9dae360ff5269666d63e4 100644 (file)
@@ -44,6 +44,8 @@
 #include <obd_class.h>
 
 #include "lov_cl_internal.h"
+#include "lov_internal.h"
+
 
 struct kmem_cache *lov_lock_kmem;
 struct kmem_cache *lov_object_kmem;
@@ -64,47 +66,47 @@ struct lu_kmem_descr lov_caches[] = {
        {
                .ckd_cache = &lov_lock_kmem,
                .ckd_name  = "lov_lock_kmem",
-               .ckd_size  = sizeof (struct lov_lock)
+               .ckd_size  = sizeof(struct lov_lock)
        },
        {
                .ckd_cache = &lov_object_kmem,
                .ckd_name  = "lov_object_kmem",
-               .ckd_size  = sizeof (struct lov_object)
+               .ckd_size  = sizeof(struct lov_object)
        },
        {
                .ckd_cache = &lov_thread_kmem,
                .ckd_name  = "lov_thread_kmem",
-               .ckd_size  = sizeof (struct lov_thread_info)
+               .ckd_size  = sizeof(struct lov_thread_info)
        },
        {
                .ckd_cache = &lov_session_kmem,
                .ckd_name  = "lov_session_kmem",
-               .ckd_size  = sizeof (struct lov_session)
+               .ckd_size  = sizeof(struct lov_session)
        },
        {
                .ckd_cache = &lov_req_kmem,
                .ckd_name  = "lov_req_kmem",
-               .ckd_size  = sizeof (struct lov_req)
+               .ckd_size  = sizeof(struct lov_req)
        },
        {
                .ckd_cache = &lovsub_lock_kmem,
                .ckd_name  = "lovsub_lock_kmem",
-               .ckd_size  = sizeof (struct lovsub_lock)
+               .ckd_size  = sizeof(struct lovsub_lock)
        },
        {
                .ckd_cache = &lovsub_object_kmem,
                .ckd_name  = "lovsub_object_kmem",
-               .ckd_size  = sizeof (struct lovsub_object)
+               .ckd_size  = sizeof(struct lovsub_object)
        },
        {
                .ckd_cache = &lovsub_req_kmem,
                .ckd_name  = "lovsub_req_kmem",
-               .ckd_size  = sizeof (struct lovsub_req)
+               .ckd_size  = sizeof(struct lovsub_req)
        },
        {
                .ckd_cache = &lov_lock_link_kmem,
                .ckd_name  = "lov_lock_link_kmem",
-               .ckd_size  = sizeof (struct lov_lock_link)
+               .ckd_size  = sizeof(struct lov_lock_link)
        },
        {
                .ckd_cache = NULL
@@ -286,7 +288,7 @@ static void lov_emerg_free(struct lov_device_emerg **emrg, int nr)
                        OBD_FREE_PTR(em);
                }
        }
-       OBD_FREE(emrg, nr * sizeof emrg[0]);
+       OBD_FREE(emrg, nr * sizeof(emrg[0]));
 }
 
 static struct lu_device *lov_device_free(const struct lu_env *env,
@@ -297,7 +299,7 @@ static struct lu_device *lov_device_free(const struct lu_env *env,
 
        cl_device_fini(lu2cl_dev(d));
        if (ld->ld_target != NULL)
-               OBD_FREE(ld->ld_target, nr * sizeof ld->ld_target[0]);
+               OBD_FREE(ld->ld_target, nr * sizeof(ld->ld_target[0]));
        if (ld->ld_emrg != NULL)
                lov_emerg_free(ld->ld_emrg, nr);
        OBD_FREE_PTR(ld);
@@ -321,7 +323,7 @@ static struct lov_device_emerg **lov_emerg_alloc(int nr)
        int i;
        int result;
 
-       OBD_ALLOC(emerg, nr * sizeof emerg[0]);
+       OBD_ALLOC(emerg, nr * sizeof(emerg[0]));
        if (emerg == NULL)
                return ERR_PTR(-ENOMEM);
        for (result = i = 0; i < nr && result == 0; i++) {
@@ -361,7 +363,7 @@ static int lov_expand_targets(const struct lu_env *env, struct lov_device *dev)
        if (sub_size < tgt_size) {
                struct lovsub_device    **newd;
                struct lov_device_emerg **emerg;
-               const size_t          sz   = sizeof newd[0];
+               const size_t          sz   = sizeof(newd[0]);
 
                emerg = lov_emerg_alloc(tgt_size);
                if (IS_ERR(emerg))
@@ -446,7 +448,7 @@ static int lov_process_config(const struct lu_env *env,
        cmd = cfg->lcfg_command;
        rc = lov_process_config_base(d->ld_obd, cfg, &index, &gen);
        if (rc == 0) {
-               switch(cmd) {
+               switch (cmd) {
                case LCFG_LOV_ADD_OBD:
                case LCFG_LOV_ADD_INA:
                        rc = lov_cl_add_target(env, d, index);
index 16770d14ee04d8686204b3cfc94af6cd5e777b5c..796da893087605bf520626ead6b5e37526317707 100644 (file)
@@ -89,6 +89,8 @@ struct lov_request_set {
 
 extern struct kmem_cache *lov_oinfo_slab;
 
+extern struct lu_kmem_descr lov_caches[];
+
 void lov_finish_set(struct lov_request_set *set);
 
 static inline void lov_get_reqset(struct lov_request_set *set)
@@ -124,7 +126,7 @@ static inline void lov_llh_put(struct lov_lock_handles *llh)
                if (atomic_read(&llh->llh_refcount))
                        return;
 
-               OBD_FREE_RCU(llh, sizeof *llh +
+               OBD_FREE_RCU(llh, sizeof(*llh) +
                             sizeof(*llh->llh_handles) * llh->llh_stripe_count,
                             &llh->llh_handle);
        }
index b611aa4e9dcb9b9a97640317e994bd6dc08975a5..2792fa5c4be2fb38dff7fc9b3d2082dbb1476a02 100644 (file)
@@ -86,7 +86,7 @@ static void lov_io_sub_inherit(struct cl_io *io, struct lov_io *lio,
        struct lov_stripe_md *lsm    = lio->lis_object->lo_lsm;
        struct cl_io     *parent = lio->lis_cl.cis_io;
 
-       switch(io->ci_type) {
+       switch (io->ci_type) {
        case CIT_SETATTR: {
                io->u.ci_setattr.sa_attr = parent->u.ci_setattr.sa_attr;
                io->u.ci_setattr.sa_valid = parent->u.ci_setattr.sa_valid;
@@ -282,7 +282,7 @@ static int lov_io_subio_init(const struct lu_env *env, struct lov_io *lio,
         * when writing a page. -jay
         */
        OBD_ALLOC_LARGE(lio->lis_subs,
-                       lsm->lsm_stripe_count * sizeof lio->lis_subs[0]);
+                       lsm->lsm_stripe_count * sizeof(lio->lis_subs[0]));
        if (lio->lis_subs != NULL) {
                lio->lis_nr_subios = lio->lis_stripe_count;
                lio->lis_single_subio_index = -1;
@@ -356,7 +356,7 @@ static void lov_io_fini(const struct lu_env *env, const struct cl_io_slice *ios)
                for (i = 0; i < lio->lis_nr_subios; i++)
                        lov_io_sub_fini(env, lio, &lio->lis_subs[i]);
                OBD_FREE_LARGE(lio->lis_subs,
-                        lio->lis_nr_subios * sizeof lio->lis_subs[0]);
+                        lio->lis_nr_subios * sizeof(lio->lis_subs[0]));
                lio->lis_nr_subios = 0;
        }
 
index ec297e87c2a2c2a048b8aa57a61203af92fbd0e3..26bc719b6dc87c5b29fc3ab829dc0d0c4ba36a91 100644 (file)
@@ -88,7 +88,7 @@ static struct lov_sublock_env *lov_sublock_env_get(const struct lu_env *env,
                        subenv->lse_io  = sub->sub_io;
                        subenv->lse_sub = sub;
                } else {
-                       subenv = (void*)sub;
+                       subenv = (void *)sub;
                }
        }
        return subenv;
@@ -167,7 +167,7 @@ static struct cl_lock *lov_sublock_alloc(const struct lu_env *env,
                        lov_sublock_env_put(subenv);
                } else {
                        /* error occurs. */
-                       sublock = (void*)subenv;
+                       sublock = (void *)subenv;
                }
 
                if (!IS_ERR(sublock))
@@ -313,7 +313,7 @@ static int lov_lock_sub_init(const struct lu_env *env,
                        nr++;
        }
        LASSERT(nr > 0);
-       OBD_ALLOC_LARGE(lck->lls_sub, nr * sizeof lck->lls_sub[0]);
+       OBD_ALLOC_LARGE(lck->lls_sub, nr * sizeof(lck->lls_sub[0]));
        if (lck->lls_sub == NULL)
                return -ENOMEM;
 
@@ -474,7 +474,7 @@ static void lov_lock_fini(const struct lu_env *env,
                         */
                        LASSERT(lck->lls_sub[i].sub_lock == NULL);
                OBD_FREE_LARGE(lck->lls_sub,
-                              lck->lls_nr * sizeof lck->lls_sub[0]);
+                              lck->lls_nr * sizeof(lck->lls_sub[0]));
        }
        OBD_SLAB_FREE_PTR(lck, lov_lock_kmem);
 }
@@ -742,7 +742,7 @@ static void lov_lock_cancel(const struct lu_env *env,
                                continue;
                        }
 
-                       switch(sublock->cll_state) {
+                       switch (sublock->cll_state) {
                        case CLS_HELD:
                                rc = cl_unuse_try(subenv->lse_env, sublock);
                                lov_sublock_release(env, lck, i, 0, 0);
index 0b47aba1332a15161fe39ea7aff15af275f11318..4783450774cd1909a39fbeaaa2d92d925eb88dad 100644 (file)
@@ -554,7 +554,7 @@ static int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
                struct lov_tgt_desc **newtgts, **old = NULL;
                __u32 newsize, oldsize = 0;
 
-               newsize = max(lov->lov_tgt_size, (__u32)2);
+               newsize = max_t(__u32, lov->lov_tgt_size, 2);
                while (newsize < index + 1)
                        newsize = newsize << 1;
                OBD_ALLOC(newtgts, sizeof(*newtgts) * newsize);
@@ -923,7 +923,7 @@ int lov_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg,
        int cmd;
        int rc = 0;
 
-       switch(cmd = lcfg->lcfg_command) {
+       switch (cmd = lcfg->lcfg_command) {
        case LCFG_LOV_ADD_OBD:
        case LCFG_LOV_ADD_INA:
        case LCFG_LOV_DEL_OBD: {
@@ -1090,7 +1090,7 @@ static int lov_destroy(const struct lu_env *env, struct obd_export *exp,
        if (rc)
                GOTO(out, rc);
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                if (oa->o_valid & OBD_MD_FLCOOKIE)
@@ -1141,7 +1141,7 @@ static int lov_getattr(const struct lu_env *env, struct obd_export *exp,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                CDEBUG(D_INFO, "objid "DOSTID"[%d] has subobj "DOSTID" at idx"
@@ -1227,7 +1227,7 @@ static int lov_getattr_async(struct obd_export *exp, struct obd_info *oinfo,
 
        if (!list_empty(&rqset->set_requests)) {
                LASSERT(rc == 0);
-               LASSERT (rqset->set_interpret == NULL);
+               LASSERT(rqset->set_interpret == NULL);
                rqset->set_interpret = lov_getattr_interpret;
                rqset->set_arg = (void *)lovset;
                return rc;
@@ -1267,7 +1267,7 @@ static int lov_setattr(const struct lu_env *env, struct obd_export *exp,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                rc = obd_setattr(env, lov->lov_tgts[req->rq_idx]->ltd_exp,
@@ -1408,7 +1408,7 @@ static int lov_punch(const struct lu_env *env, struct obd_export *exp,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                rc = obd_punch(env, lov->lov_tgts[req->rq_idx]->ltd_exp,
@@ -1472,7 +1472,7 @@ static int lov_sync(const struct lu_env *env, struct obd_export *exp,
        CDEBUG(D_INFO, "fsync objid "DOSTID" ["LPX64", "LPX64"]\n",
               POSTID(&set->set_oi->oi_oa->o_oi), start, end);
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                rc = obd_sync(env, lov->lov_tgts[req->rq_idx]->ltd_exp,
@@ -1557,7 +1557,7 @@ static int lov_brw(int cmd, struct obd_export *exp, struct obd_info *oinfo,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                struct obd_export *sub_exp;
                struct brw_page *sub_pga;
                req = list_entry(pos, struct lov_request, rq_link);
@@ -1612,7 +1612,7 @@ static int lov_enqueue(struct obd_export *exp, struct obd_info *oinfo,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                rc = obd_enqueue(lov->lov_tgts[req->rq_idx]->ltd_exp,
@@ -1828,7 +1828,7 @@ static int lov_statfs_async(struct obd_export *exp, struct obd_info *oinfo,
        if (rc)
                return rc;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
                rc = obd_statfs_async(lov->lov_tgts[req->rq_idx]->ltd_exp,
                                      &req->rq_oi, max_age, rqset);
@@ -1909,7 +1909,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                                         (int) sizeof(struct obd_uuid))))
                        return -EFAULT;
 
-               flags = uarg ? *(__u32*)uarg : 0;
+               flags = uarg ? *(__u32 *)uarg : 0;
                /* got statfs data */
                rc = obd_statfs(NULL, lov->lov_tgts[index]->ltd_exp, &stat_buf,
                                cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
@@ -2495,7 +2495,7 @@ static int lov_get_info(const struct lu_env *env, struct obd_export *exp,
                GOTO(out, rc);
        } else if (KEY_IS(KEY_CONNECT_FLAG)) {
                struct lov_tgt_desc *tgt;
-               __u64 ost_idx = *((__u64*)val);
+               __u64 ost_idx = *((__u64 *)val);
 
                LASSERT(*vallen == sizeof(__u64));
                LASSERT(ost_idx < lov->desc.ld_tgt_count);
@@ -2564,7 +2564,7 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp,
 
        for (i = 0; i < count; i++, val = (char *)val + incr) {
                if (next_id) {
-                       tgt = lov->lov_tgts[((struct obd_id_info*)val)->idx];
+                       tgt = lov->lov_tgts[((struct obd_id_info *)val)->idx];
                } else {
                        tgt = lov->lov_tgts[i];
                }
@@ -2593,9 +2593,9 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp,
                } else if (next_id) {
                        err = obd_set_info_async(env, tgt->ltd_exp,
                                         keylen, key, vallen,
-                                        ((struct obd_id_info*)val)->data, set);
+                                        ((struct obd_id_info *)val)->data, set);
                } else if (capa) {
-                       struct mds_capa_info *info = (struct mds_capa_info*)val;
+                       struct mds_capa_info *info = (struct mds_capa_info *)val;
 
                        LASSERT(vallen == sizeof(*info));
 
@@ -2781,7 +2781,7 @@ struct obd_ops lov_obd_ops = {
        .o_setup               = lov_setup,
        .o_precleanup     = lov_precleanup,
        .o_cleanup           = lov_cleanup,
-       //.o_process_config      = lov_process_config,
+       /*.o_process_config      = lov_process_config,*/
        .o_connect           = lov_connect,
        .o_disconnect     = lov_disconnect,
        .o_statfs             = lov_statfs,
@@ -2823,8 +2823,6 @@ struct obd_ops lov_obd_ops = {
 
 struct kmem_cache *lov_oinfo_slab;
 
-extern struct lu_kmem_descr lov_caches[];
-
 int __init lov_init(void)
 {
        struct lprocfs_static_vars lvars = { 0 };
index 84e55ce3ccd2217236ce176fe3ee7cb7b20cc762..cf2fa8abfb1dede0e69de8d8a59a5f97a82816c9 100644 (file)
@@ -214,7 +214,7 @@ static int lov_init_raid0(const struct lu_env *env,
        r0->lo_nr  = lsm->lsm_stripe_count;
        LASSERT(r0->lo_nr <= lov_targets_nr(dev));
 
-       OBD_ALLOC_LARGE(r0->lo_sub, r0->lo_nr * sizeof r0->lo_sub[0]);
+       OBD_ALLOC_LARGE(r0->lo_sub, r0->lo_nr * sizeof(r0->lo_sub[0]));
        if (r0->lo_sub != NULL) {
                result = 0;
                subconf->coc_inode = conf->coc_inode;
@@ -368,7 +368,7 @@ static void lov_fini_raid0(const struct lu_env *env, struct lov_object *lov,
        struct lov_layout_raid0 *r0 = &state->raid0;
 
        if (r0->lo_sub != NULL) {
-               OBD_FREE_LARGE(r0->lo_sub, r0->lo_nr * sizeof r0->lo_sub[0]);
+               OBD_FREE_LARGE(r0->lo_sub, r0->lo_nr * sizeof(r0->lo_sub[0]));
                r0->lo_sub = NULL;
        }
 
index 55ec26778f8043cb16276f7b1c35404d772c92af..ec6f6e0572ae906fd43ce7f3530449cd0e1eee62 100644 (file)
@@ -121,7 +121,7 @@ void lov_dump_lmm(int level, void *lmm)
 do {                                                               \
        if (!(test)) lov_dump_lmm(D_ERROR, lmm);                        \
        LASSERT(test); /* so we know what assertion failed */      \
-} while(0)
+} while (0)
 
 /* Pack LOV object metadata for disk storage.  It is packed in LE byte
  * order and is opaque to the networking layer.
@@ -630,22 +630,22 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm,
        /* FIXME: Bug 1185 - copy fields properly when structs change */
        /* struct lov_user_md_v3 and struct lov_mds_md_v3 must be the same */
        CLASSERT(sizeof(lum) == sizeof(struct lov_mds_md_v3));
-       CLASSERT(sizeof lum.lmm_objects[0] == sizeof lmmk->lmm_objects[0]);
+       CLASSERT(sizeof(lum.lmm_objects[0]) == sizeof(lmmk->lmm_objects[0]));
 
        if ((cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) &&
            ((lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) ||
            (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)))) {
                lustre_swab_lov_mds_md(lmmk);
                lustre_swab_lov_user_md_objects(
-                               (struct lov_user_ost_data*)lmmk->lmm_objects,
+                               (struct lov_user_ost_data *)lmmk->lmm_objects,
                                lmmk->lmm_stripe_count);
        }
        if (lum.lmm_magic == LOV_USER_MAGIC) {
                /* User request for v1, we need skip lmm_pool_name */
                if (lmmk->lmm_magic == LOV_MAGIC_V3) {
-                       memmove((char*)(&lmmk->lmm_stripe_count) +
+                       memmove((char *)(&lmmk->lmm_stripe_count) +
                                sizeof(lmmk->lmm_stripe_count),
-                               ((struct lov_mds_md_v3*)lmmk)->lmm_objects,
+                               ((struct lov_mds_md_v3 *)lmmk)->lmm_objects,
                                lmmk->lmm_stripe_count *
                                sizeof(struct lov_ost_data_v1));
                        lmm_size -= LOV_MAXPOOLNAME;
index 61e6d0b46c98e4898a43867ea0e79b20f8ada587..bf324ae2946f11cac0b0cdd4a04796094756d102 100644 (file)
@@ -245,7 +245,7 @@ int lov_update_enqueue_set(struct lov_request *req, __u32 mode, int rc)
        osc_update_enqueue(lov_lockhp, loi, oi->oi_flags,
                           &req->rq_oi.oi_md->lsm_oinfo[0]->loi_lvb, mode, rc);
        if (rc == ELDLM_LOCK_ABORTED && (oi->oi_flags & LDLM_FL_HAS_INTENT))
-               memset(lov_lockhp, 0, sizeof *lov_lockhp);
+               memset(lov_lockhp, 0, sizeof(*lov_lockhp));
        rc = lov_update_enqueue_lov(set->set_exp, lov_lockhp, loi, oi->oi_flags,
                                    req->rq_idx, &oi->oi_md->lsm_oi, rc);
        lov_stripe_unlock(oi->oi_md);
@@ -343,7 +343,7 @@ static struct lov_lock_handles *lov_llh_new(struct lov_stripe_md *lsm)
 {
        struct lov_lock_handles *llh;
 
-       OBD_ALLOC(llh, sizeof *llh +
+       OBD_ALLOC(llh, sizeof(*llh) +
                  sizeof(*llh->llh_handles) * lsm->lsm_stripe_count);
        if (llh == NULL)
                return NULL;
@@ -630,7 +630,7 @@ static int common_attr_done(struct lov_request_set *set)
        if (tmp_oa == NULL)
                GOTO(out, rc = -ENOMEM);
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                if (!req->rq_complete || req->rq_rc)
@@ -669,7 +669,7 @@ static int brw_done(struct lov_request_set *set)
        struct list_head *pos;
        struct lov_request *req;
 
-       list_for_each (pos, &set->set_list) {
+       list_for_each(pos, &set->set_list) {
                req = list_entry(pos, struct lov_request, rq_link);
 
                if (!req->rq_complete || req->rq_rc)
@@ -1315,7 +1315,7 @@ out_set:
                        (tot) = LOV_U64_MAX;                        \
                else                                                \
                        (tot) += (add);                          \
-       } while(0)
+       } while (0)
 
 int lov_fini_statfs(struct obd_device *obd, struct obd_statfs *osfs,int success)
 {
index e86df7356cb1ee141e637d29b7e503f883bdbace..0d6ed69ddb223af36efff72419abad7bf6a91038 100644 (file)
@@ -50,9 +50,8 @@ static struct fsfilt_operations *fsfilt_search_type(const char *type)
 
        list_for_each(p, &fsfilt_types) {
                found = list_entry(p, struct fsfilt_operations, fs_list);
-               if (!strcmp(found->fs_type, type)) {
+               if (!strcmp(found->fs_type, type))
                        return found;
-               }
        }
        return NULL;
 }
@@ -62,7 +61,8 @@ int fsfilt_register_ops(struct fsfilt_operations *fs_ops)
        struct fsfilt_operations *found;
 
        /* lock fsfilt_types list */
-       if ((found = fsfilt_search_type(fs_ops->fs_type))) {
+       found = fsfilt_search_type(fs_ops->fs_type);
+       if (found) {
                if (found != fs_ops) {
                        CERROR("different operations for type %s\n",
                               fs_ops->fs_type);
@@ -103,14 +103,16 @@ struct fsfilt_operations *fsfilt_get_ops(const char *type)
        struct fsfilt_operations *fs_ops;
 
        /* lock fsfilt_types list */
-       if (!(fs_ops = fsfilt_search_type(type))) {
+       fs_ops = fsfilt_search_type(type);
+       if (!fs_ops) {
                char name[32];
                int rc;
 
                snprintf(name, sizeof(name) - 1, "fsfilt_%s", type);
                name[sizeof(name) - 1] = '\0';
 
-               if (!(rc = request_module("%s", name))) {
+               rc = request_module("%s", name);
+               if (!rc) {
                        fs_ops = fsfilt_search_type(type);
                        CDEBUG(D_INFO, "Loaded module '%s'\n", name);
                        if (!fs_ops)
index 97a8be2300dd1ad2ee417d617107766aad895f3b..b21e40cdacab21b6f80f94b1c3f324577e2ee9db 100644 (file)
@@ -154,11 +154,10 @@ int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid)
                                spin_lock(&stats->ls_lock);
                        if (stats->ls_biggest_alloc_num <= cpuid)
                                stats->ls_biggest_alloc_num = cpuid + 1;
-                       if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) {
+                       if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
                                spin_unlock_irqrestore(&stats->ls_lock, flags);
-                       } else {
+                       else
                                spin_unlock(&stats->ls_lock);
-                       }
                }
                /* initialize the ls_percpu[cpuid] non-zero counter */
                for (i = 0; i < stats->ls_num; ++i) {
index 18e1b47a1d65aaebf5c3312670e43017232780f8..ea377155078853db14711d5ae526401f94854f89 100644 (file)
@@ -80,7 +80,8 @@ static void push_group_info(struct lvfs_run_ctxt *save,
                struct cred *cred;
                task_lock(current);
                save->group_info = current_cred()->group_info;
-               if ((cred = prepare_creds())) {
+               cred = prepare_creds();
+               if (cred) {
                        cred->group_info = ginfo;
                        commit_creds(cred);
                }
@@ -96,7 +97,8 @@ static void pop_group_info(struct lvfs_run_ctxt *save,
        } else {
                struct cred *cred;
                task_lock(current);
-               if ((cred = prepare_creds())) {
+               cred = prepare_creds();
+               if (cred) {
                        cred->group_info = save->group_info;
                        commit_creds(cred);
                }
@@ -137,7 +139,8 @@ void push_ctxt(struct lvfs_run_ctxt *save, struct lvfs_run_ctxt *new_ctx,
                save->luc.luc_fsgid = current_fsgid();
                save->luc.luc_cap = current_cap();
 
-               if ((cred = prepare_creds())) {
+               cred = prepare_creds();
+               if (cred) {
                        cred->uid = uc->luc_uid;
                        cred->gid = uc->luc_gid;
                        cred->fsuid = uc->luc_fsuid;
@@ -180,7 +183,8 @@ void pop_ctxt(struct lvfs_run_ctxt *saved, struct lvfs_run_ctxt *new_ctx,
        current->fs->umask = saved->luc.luc_umask;
        if (uc) {
                struct cred *cred;
-               if ((cred = prepare_creds())) {
+               cred = prepare_creds();
+               if (cred) {
                        cred->uid = saved->luc.luc_uid;
                        cred->gid = saved->luc.luc_gid;
                        cred->fsuid = saved->luc.luc_fsuid;
@@ -253,32 +257,32 @@ __s64 lprocfs_read_helper(struct lprocfs_counter *lc,
                return 0;
 
        switch (field) {
-               case LPROCFS_FIELDS_FLAGS_CONFIG:
-                       ret = header->lc_config;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_SUM:
-                       ret = lc->lc_sum;
-                       if ((flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
-                               ret += lc->lc_sum_irq;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_MIN:
-                       ret = lc->lc_min;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_MAX:
-                       ret = lc->lc_max;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_AVG:
-                       ret = (lc->lc_max - lc->lc_min) / 2;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_SUMSQUARE:
-                       ret = lc->lc_sumsquare;
-                       break;
-               case LPROCFS_FIELDS_FLAGS_COUNT:
-                       ret = lc->lc_count;
-                       break;
-               default:
-                       break;
-       };
+       case LPROCFS_FIELDS_FLAGS_CONFIG:
+               ret = header->lc_config;
+               break;
+       case LPROCFS_FIELDS_FLAGS_SUM:
+               ret = lc->lc_sum;
+               if ((flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
+                       ret += lc->lc_sum_irq;
+               break;
+       case LPROCFS_FIELDS_FLAGS_MIN:
+               ret = lc->lc_min;
+               break;
+       case LPROCFS_FIELDS_FLAGS_MAX:
+               ret = lc->lc_max;
+               break;
+       case LPROCFS_FIELDS_FLAGS_AVG:
+               ret = (lc->lc_max - lc->lc_min) / 2;
+               break;
+       case LPROCFS_FIELDS_FLAGS_SUMSQUARE:
+               ret = lc->lc_sumsquare;
+               break;
+       case LPROCFS_FIELDS_FLAGS_COUNT:
+               ret = lc->lc_count;
+               break;
+       default:
+               break;
+       }
 
        return ret;
 }
index 42697934155493e5c1c5a79576bce699f3f1ee28..e048500edd60c680aa280d872fe34f576ba66172 100644 (file)
@@ -1387,7 +1387,7 @@ static void cl_req_free(const struct lu_env *env, struct cl_req *req)
                                cl_object_put(env, obj);
                        }
                }
-               OBD_FREE(req->crq_o, req->crq_nrobjs * sizeof req->crq_o[0]);
+               OBD_FREE(req->crq_o, req->crq_nrobjs * sizeof(req->crq_o[0]));
        }
        OBD_FREE_PTR(req);
 }
@@ -1452,7 +1452,7 @@ struct cl_req *cl_req_alloc(const struct lu_env *env, struct cl_page *page,
        if (req != NULL) {
                int result;
 
-               OBD_ALLOC(req->crq_o, nr_objects * sizeof req->crq_o[0]);
+               OBD_ALLOC(req->crq_o, nr_objects * sizeof(req->crq_o[0]));
                if (req->crq_o != NULL) {
                        req->crq_nrobjs = nr_objects;
                        req->crq_type = crt;
@@ -1642,7 +1642,7 @@ int cl_sync_io_wait(const struct lu_env *env, struct cl_io *io,
                cpu_relax();
        }
 
-       POISON(anchor, 0x5a, sizeof *anchor);
+       POISON(anchor, 0x5a, sizeof(*anchor));
        return rc;
 }
 EXPORT_SYMBOL(cl_sync_io_wait);
index b1024a6d37dd95ef215a489d07b5de76f2ec3f66..4afd962cdb64db50c83f5312b656ed0fe6131b4f 100644 (file)
@@ -178,7 +178,7 @@ EXPORT_SYMBOL(obd_alloc_fail);
 static inline void obd_data2conn(struct lustre_handle *conn,
                                 struct obd_ioctl_data *data)
 {
-       memset(conn, 0, sizeof *conn);
+       memset(conn, 0, sizeof(*conn));
        conn->cookie = data->ioc_cookie;
 }
 
index d9e6d12215f904307b7d42483fbac272a19b002e..178f89eccab11d25229c801f2e2ad9f244f33c07 100644 (file)
@@ -242,7 +242,7 @@ static int llog_test_3(const struct lu_env *env, struct obd_device *obd,
 
                hdr.lrh_len = 8;
                hdr.lrh_type = OBD_CFG_REC;
-               memset(buf, 0, sizeof buf);
+               memset(buf, 0, sizeof(buf));
                rc = llog_write(env, llh, &hdr, NULL, 0, buf, -1);
                if (rc < 0) {
                        CERROR("3b: write 10 records failed at #%d: %d\n",
@@ -277,8 +277,8 @@ static int llog_test_3(const struct lu_env *env, struct obd_device *obd,
                char                    buf_even[24];
                char                    buf_odd[32];
 
-               memset(buf_odd, 0, sizeof buf_odd);
-               memset(buf_even, 0, sizeof buf_even);
+               memset(buf_odd, 0, sizeof(buf_odd));
+               memset(buf_even, 0, sizeof(buf_even));
                if ((i % 2) == 0) {
                        hdr.lrh_len = 24;
                        hdr.lrh_type = OBD_CFG_REC;
index 3a3d5bc5a628a05e45def8d74112e55138655a80..e8f260781c0ef96b747145c7286628d2cad99102 100644 (file)
@@ -980,7 +980,7 @@ int lu_site_init(struct lu_site *s, struct lu_device *top)
        int bits;
        int i;
 
-       memset(s, 0, sizeof *s);
+       memset(s, 0, sizeof(*s));
        bits = lu_htable_order();
        snprintf(name, 16, "lu_site_%s", top->ld_type->ldt_name);
        for (bits = min(max(LU_SITE_BITS_MIN, bits), LU_SITE_BITS_MAX);
@@ -1110,7 +1110,7 @@ int lu_device_init(struct lu_device *d, struct lu_device_type *t)
 {
        if (t->ldt_device_nr++ == 0 && t->ldt_ops->ldto_start != NULL)
                t->ldt_ops->ldto_start(t);
-       memset(d, 0, sizeof *d);
+       memset(d, 0, sizeof(*d));
        atomic_set(&d->ld_ref, 0);
        d->ld_type = t;
        lu_ref_init(&d->ld_reference);
@@ -1206,7 +1206,7 @@ EXPORT_SYMBOL(lu_object_add);
  */
 int lu_object_header_init(struct lu_object_header *h)
 {
-       memset(h, 0, sizeof *h);
+       memset(h, 0, sizeof(*h));
        atomic_set(&h->loh_ref, 1);
        INIT_HLIST_NODE(&h->loh_hash);
        INIT_LIST_HEAD(&h->loh_lru);
@@ -1525,7 +1525,7 @@ static void keys_fini(struct lu_context *ctx)
        for (i = 0; i < ARRAY_SIZE(lu_keys); ++i)
                key_fini(ctx, i);
 
-       OBD_FREE(ctx->lc_value, ARRAY_SIZE(lu_keys) * sizeof ctx->lc_value[0]);
+       OBD_FREE(ctx->lc_value, ARRAY_SIZE(lu_keys) * sizeof(ctx->lc_value[0]));
        ctx->lc_value = NULL;
 }
 
@@ -1574,7 +1574,8 @@ static int keys_fill(struct lu_context *ctx)
 
 static int keys_init(struct lu_context *ctx)
 {
-       OBD_ALLOC(ctx->lc_value, ARRAY_SIZE(lu_keys) * sizeof ctx->lc_value[0]);
+       OBD_ALLOC(ctx->lc_value,
+                 ARRAY_SIZE(lu_keys) * sizeof(ctx->lc_value[0]));
        if (likely(ctx->lc_value != NULL))
                return keys_fill(ctx);
 
@@ -1588,7 +1589,7 @@ int lu_context_init(struct lu_context *ctx, __u32 tags)
 {
        int     rc;
 
-       memset(ctx, 0, sizeof *ctx);
+       memset(ctx, 0, sizeof(*ctx));
        ctx->lc_state = LCS_INITIALIZED;
        ctx->lc_tags = tags;
        if (tags & LCT_REMEMBER) {
index d0a64ff53581e5871abf99379fe387e0b979dd2c..73e2571f463ffa80c65facd2a757832301aaf7e4 100644 (file)
@@ -417,7 +417,7 @@ int class_attach(struct lustre_cfg *lcfg)
 
        /* do the attach */
        if (OBP(obd, attach)) {
-               rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
+               rc = OBP(obd, attach)(obd, sizeof(*lcfg), lcfg);
                if (rc)
                        GOTO(out, rc = -EINVAL);
        }
@@ -900,7 +900,7 @@ void class_del_profile(const char *prof)
                OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
                if (lprof->lp_md)
                        OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
-               OBD_FREE(lprof, sizeof *lprof);
+               OBD_FREE(lprof, sizeof(*lprof));
        }
 }
 EXPORT_SYMBOL(class_del_profile);
@@ -916,7 +916,7 @@ void class_del_profiles(void)
                OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
                if (lprof->lp_md)
                        OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
-               OBD_FREE(lprof, sizeof *lprof);
+               OBD_FREE(lprof, sizeof(*lprof));
        }
 }
 EXPORT_SYMBOL(class_del_profiles);
index af5f27f82bc5b157b02de284c2dff886c6974dee..e87a19900770574282e8a3da3357efc78b0292b1 100644 (file)
@@ -48,7 +48,7 @@ static inline __u32 consume(int nob, __u8 **ptr)
 {
        __u32 value;
 
-       LASSERT(nob <= sizeof value);
+       LASSERT(nob <= sizeof(value));
 
        for (value = 0; nob > 0; --nob)
                value = (value << 8) | *((*ptr)++);
@@ -61,7 +61,7 @@ static void uuid_unpack(class_uuid_t in, __u16 *uu, int nr)
 {
        __u8 *ptr = in;
 
-       LASSERT(nr * sizeof *uu == sizeof(class_uuid_t));
+       LASSERT(nr * sizeof(*uu) == sizeof(class_uuid_t));
 
        while (nr-- > 0)
                CONSUME(uu[nr], &ptr);
index c8b43442dc74be8c8cf1ee3f5b38470f63617e71..1fb0ac4e920d58136163b7bd244fe782ecdc493a 100644 (file)
@@ -1089,7 +1089,7 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d,
                } else {
                        struct lustre_md *md;
                        md = &info->eti_md;
-                       memset(md, 0, sizeof *md);
+                       memset(md, 0, sizeof(*md));
                        md->lsm = lsm;
                        conf->eoc_cl.u.coc_md = md;
                }
index 5d7bdbfc871af2c9e0e2dd3b4bad76e3771f1a31..c90abfbb1d7a52cd25374d1336ab014a5252d08a 100644 (file)
@@ -862,7 +862,7 @@ static int osc_ldlm_glimpse_ast(struct ldlm_lock *dlmlock, void *data)
                        cap = &req->rq_pill;
                        req_capsule_extend(cap, &RQF_LDLM_GL_CALLBACK);
                        req_capsule_set_size(cap, &RMF_DLM_LVB, RCL_SERVER,
-                                            sizeof *lvb);
+                                            sizeof(*lvb));
                        result = req_capsule_server_pack(cap);
                        if (result == 0) {
                                lvb = req_capsule_server_get(cap, &RMF_DLM_LVB);
index d272322b29b6618ddad867720ae8be6c0b5825c2..6c20b8ecfb8200080c599236c6cb4445bde940ff 100644 (file)
@@ -245,7 +245,7 @@ static int osc_page_cache_add(const struct lu_env *env,
 void osc_index2policy(ldlm_policy_data_t *policy, const struct cl_object *obj,
                      pgoff_t start, pgoff_t end)
 {
-       memset(policy, 0, sizeof *policy);
+       memset(policy, 0, sizeof(*policy));
        policy->l_extent.start = cl_offset(obj, start);
        policy->l_extent.end   = cl_offset(obj, end + 1) - 1;
 }
index ee6707a5ea9d8e9ddb99053fa479836bfcc5cb77..cb197782d9a3378c0060a21614a8a5fda06be166 100644 (file)
@@ -2554,7 +2554,7 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id,
                }
 
                req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
-                                    sizeof *lvb);
+                                    sizeof(*lvb));
                ptlrpc_request_set_replen(req);
        }
 
index 810a458caed73aaea8a34e0ba1abb65f12336d0a..c2ab0c8c4d42520b16be642385636240f7cb8a9e 100644 (file)
@@ -817,7 +817,7 @@ struct ptlrpc_request_set *ptlrpc_prep_set(void)
 {
        struct ptlrpc_request_set *set;
 
-       OBD_ALLOC(set, sizeof *set);
+       OBD_ALLOC(set, sizeof(*set));
        if (!set)
                return NULL;
        atomic_set(&set->set_refcount, 1);
@@ -2690,7 +2690,7 @@ int ptlrpc_replay_req(struct ptlrpc_request *req)
 
        LASSERT (sizeof (*aa) <= sizeof (req->rq_async_args));
        aa = ptlrpc_req_async_args(req);
-       memset(aa, 0, sizeof *aa);
+       memset(aa, 0, sizeof(*aa));
 
        /* Prepare request to be resent with ptlrpcd */
        aa->praa_old_state = req->rq_send_state;
index 5ca69aec72e1594ffc8235ede4447ee63c31ead8..7b96a0e88cdbb5cd1f63d0096c2d7d81d737ea05 100644 (file)
@@ -682,7 +682,7 @@ int ptlrpc_connect_import(struct obd_import *imp)
 
        CLASSERT(sizeof (*aa) <= sizeof (request->rq_async_args));
        aa = ptlrpc_req_async_args(request);
-       memset(aa, 0, sizeof *aa);
+       memset(aa, 0, sizeof(*aa));
 
        aa->pcaa_peer_committed = committed_before_reconnect;
        aa->pcaa_initial_connect = initial_connect;
index 2f55ce26ccbafc6dbded4a8ad08c69af9fb4c617..d0a6e56892271c2bc00072e207f74248f84209a1 100644 (file)
@@ -1669,7 +1669,7 @@ void req_capsule_init(struct req_capsule *pill,
        if (req != NULL && pill == &req->rq_pill && req->rq_pill_init)
                return;
 
-       memset(pill, 0, sizeof *pill);
+       memset(pill, 0, sizeof(*pill));
        pill->rc_req = req;
        pill->rc_loc = location;
        req_capsule_init_area(pill);
index 6547f46a7729f2f95c16f9bdff5e334a43806eea..316103ab7c3c056fa760db06cc49babb9d6ab28b 100644 (file)
@@ -207,7 +207,7 @@ static void enc_pools_release_free_pages(long npages)
                        p_idx++;
                        g_idx = 0;
                }
-       };
+       }
 
        /* free unused pools */
        while (p_idx_max1 < p_idx_max2) {
index acf75f3873d1ffb0ab9cc4258150b3a9a1b2e3ba..21de868da522ae813d798d588132f74c5d819f7b 100644 (file)
@@ -263,7 +263,7 @@ static struct ptlrpc_hr_service             ptlrpc_hr;
  */
 static void rs_batch_init(struct rs_batch *b)
 {
-       memset(b, 0, sizeof *b);
+       memset(b, 0, sizeof(*b));
        INIT_LIST_HEAD(&b->rsb_replies);
 }
 
@@ -1306,12 +1306,12 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
        }
        newdl = cfs_time_current_sec() + at_get(&svcpt->scp_at_estimate);
 
-       OBD_ALLOC(reqcopy, sizeof *reqcopy);
+       OBD_ALLOC(reqcopy, sizeof(*reqcopy));
        if (reqcopy == NULL)
                return -ENOMEM;
        OBD_ALLOC_LARGE(reqmsg, req->rq_reqlen);
        if (!reqmsg) {
-               OBD_FREE(reqcopy, sizeof *reqcopy);
+               OBD_FREE(reqcopy, sizeof(*reqcopy));
                return -ENOMEM;
        }
 
@@ -1370,7 +1370,7 @@ out_put:
 out:
        sptlrpc_svc_ctx_decref(reqcopy);
        OBD_FREE_LARGE(reqmsg, req->rq_reqlen);
-       OBD_FREE(reqcopy, sizeof *reqcopy);
+       OBD_FREE(reqcopy, sizeof(*reqcopy));
        return rc;
 }
 
index 46ed8324503500290885268e36cd0587639c8b8f..6f756830c421a3c8e67bfd8d078af8130b52053d 100644 (file)
@@ -15,6 +15,8 @@
  * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 
 static unsigned int assume_endura;
 module_param(assume_endura, int, 0644);
-MODULE_PARM_DESC(assume_endura, "when probing fails, "
-                               "hardware is a Pelco Endura");
+MODULE_PARM_DESC(assume_endura,
+                       "when probing fails, hardware is a Pelco Endura");
 
-/* #define GO7007_USB_DEBUG */
 /* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
 
 #define        HPI_STATUS_ADDR 0xFFF4
@@ -662,9 +663,7 @@ static int go7007_usb_interface_reset(struct go7007 *go)
 
        if (usb->board->flags & GO7007_USB_EZUSB) {
                /* Reset buffer in EZ-USB */
-#ifdef GO7007_USB_DEBUG
-               printk(KERN_DEBUG "go7007-usb: resetting EZ-USB buffers\n");
-#endif
+               pr_debug("resetting EZ-USB buffers\n");
                if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
                    go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
                        return -1;
@@ -678,8 +677,7 @@ static int go7007_usb_interface_reset(struct go7007 *go)
        /* Wait for an interrupt to indicate successful hardware reset */
        if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
                        (intr_val & ~0x1) != 0x55aa) {
-               printk(KERN_ERR
-                       "go7007-usb: unable to reset the USB interface\n");
+               pr_err("unable to reset the USB interface\n");
                return -1;
        }
        return 0;
@@ -693,10 +691,7 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
        u16 status_reg = 0;
        int timeout = 500;
 
-#ifdef GO7007_USB_DEBUG
-       printk(KERN_DEBUG
-               "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
-#endif
+       pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
 
        for (i = 0; i < 100; ++i) {
                r = usb_control_msg(usb->usbdev,
@@ -714,9 +709,7 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
        if (r < 0)
                goto write_int_error;
        if (i == 100) {
-               printk(KERN_ERR
-                       "go7007-usb: device is hung, status reg = 0x%04x\n",
-                       status_reg);
+               pr_err("device is hung, status reg = 0x%04x\n", status_reg);
                return -1;
        }
        r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
@@ -732,7 +725,7 @@ static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
        return 0;
 
 write_int_error:
-       printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
+       pr_err("error in WriteInterrupt: %d\n", r);
        return r;
 }
 
@@ -743,10 +736,7 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
        int r;
        int timeout = 500;
 
-#ifdef GO7007_USB_DEBUG
-       printk(KERN_DEBUG
-               "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
-#endif
+       pr_debug("WriteInterrupt: %04x %04x\n", addr, data);
 
        go->usb_buf[0] = data & 0xff;
        go->usb_buf[1] = data >> 8;
@@ -757,7 +747,7 @@ static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
                        USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa,
                        0xf0f0, go->usb_buf, 8, timeout);
        if (r < 0) {
-               printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
+               pr_err("error in WriteInterrupt: %d\n", r);
                return r;
        }
        return 0;
@@ -772,23 +762,19 @@ static void go7007_usb_readinterrupt_complete(struct urb *urb)
        if (status) {
                if (status != -ESHUTDOWN &&
                                go->status != STATUS_SHUTDOWN) {
-                       printk(KERN_ERR
-                               "go7007-usb: error in read interrupt: %d\n",
-                               urb->status);
+                       pr_err("error in read interrupt: %d\n", urb->status);
                } else {
                        wake_up(&go->interrupt_waitq);
                        return;
                }
        } else if (urb->actual_length != urb->transfer_buffer_length) {
-               printk(KERN_ERR "go7007-usb: short read in interrupt pipe!\n");
+               pr_err("short read in interrupt pipe!\n");
        } else {
                go->interrupt_available = 1;
                go->interrupt_data = __le16_to_cpu(regs[0]);
                go->interrupt_value = __le16_to_cpu(regs[1]);
-#ifdef GO7007_USB_DEBUG
-               printk(KERN_DEBUG "go7007-usb: ReadInterrupt: %04x %04x\n",
+               pr_debug("ReadInterrupt: %04x %04x\n",
                                go->interrupt_value, go->interrupt_data);
-#endif
        }
 
        wake_up(&go->interrupt_waitq);
@@ -801,8 +787,7 @@ static int go7007_usb_read_interrupt(struct go7007 *go)
 
        r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
        if (r < 0) {
-               printk(KERN_ERR
-                       "go7007-usb: unable to submit interrupt urb: %d\n", r);
+               pr_err("unable to submit interrupt urb: %d\n", r);
                return r;
        }
        return 0;
@@ -818,18 +803,17 @@ static void go7007_usb_read_video_pipe_complete(struct urb *urb)
                return;
        }
        if (status) {
-               printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
-                       status);
+               pr_err("error in video pipe: %d\n", status);
                return;
        }
        if (urb->actual_length != urb->transfer_buffer_length) {
-               printk(KERN_ERR "go7007-usb: short read in video pipe!\n");
+               pr_err("short read in video pipe!\n");
                return;
        }
        go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
        r = usb_submit_urb(urb, GFP_ATOMIC);
        if (r < 0)
-               printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", r);
+               pr_err("error in video pipe: %d\n", r);
 }
 
 static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
@@ -840,19 +824,19 @@ static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
        if (!vb2_is_streaming(&go->vidq))
                return;
        if (status) {
-               printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
+               pr_err("error in audio pipe: %d\n",
                        status);
                return;
        }
        if (urb->actual_length != urb->transfer_buffer_length) {
-               printk(KERN_ERR "go7007-usb: short read in audio pipe!\n");
+               pr_err("short read in audio pipe!\n");
                return;
        }
        if (go->audio_deliver != NULL)
                go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
        r = usb_submit_urb(urb, GFP_ATOMIC);
        if (r < 0)
-               printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", r);
+               pr_err("error in audio pipe: %d\n", r);
 }
 
 static int go7007_usb_stream_start(struct go7007 *go)
@@ -863,8 +847,7 @@ static int go7007_usb_stream_start(struct go7007 *go)
        for (i = 0; i < 8; ++i) {
                r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
                if (r < 0) {
-                       printk(KERN_ERR "go7007-usb: error submitting video "
-                                       "urb %d: %d\n", i, r);
+                       pr_err("error submitting video urb %d: %d\n", i, r);
                        goto video_submit_failed;
                }
        }
@@ -874,8 +857,7 @@ static int go7007_usb_stream_start(struct go7007 *go)
        for (i = 0; i < 8; ++i) {
                r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
                if (r < 0) {
-                       printk(KERN_ERR "go7007-usb: error submitting audio "
-                                       "urb %d: %d\n", i, r);
+                       pr_err("error submitting audio urb %d: %d\n", i, r);
                        goto audio_submit_failed;
                }
        }
@@ -911,9 +893,7 @@ static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
        int transferred, pipe;
        int timeout = 500;
 
-#ifdef GO7007_USB_DEBUG
-       printk(KERN_DEBUG "go7007-usb: DownloadBuffer sending %d bytes\n", len);
-#endif
+       pr_debug("DownloadBuffer sending %d bytes\n", len);
 
        if (usb->board->flags & GO7007_USB_EZUSB)
                pipe = usb_sndbulkpipe(usb->usbdev, 2);
@@ -999,9 +979,8 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
                                !(msgs[i].flags & I2C_M_RD) &&
                                (msgs[i + 1].flags & I2C_M_RD)) {
 #ifdef GO7007_I2C_DEBUG
-                       printk(KERN_DEBUG "go7007-usb: i2c write/read %d/%d "
-                                       "bytes on %02x\n", msgs[i].len,
-                                       msgs[i + 1].len, msgs[i].addr);
+                       pr_debug("i2c write/read %d/%d bytes on %02x\n",
+                               msgs[i].len, msgs[i + 1].len, msgs[i].addr);
 #endif
                        buf[0] = 0x01;
                        buf[1] = msgs[i].len + 1;
@@ -1011,9 +990,8 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
                        buf[buf_len++] = msgs[++i].len;
                } else if (msgs[i].flags & I2C_M_RD) {
 #ifdef GO7007_I2C_DEBUG
-                       printk(KERN_DEBUG "go7007-usb: i2c read %d "
-                                       "bytes on %02x\n", msgs[i].len,
-                                       msgs[i].addr);
+                       pr_debug("i2c read %d bytes on %02x\n",
+                                       msgs[i].len, msgs[i].addr);
 #endif
                        buf[0] = 0x01;
                        buf[1] = 1;
@@ -1022,9 +1000,8 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
                        buf_len = 4;
                } else {
 #ifdef GO7007_I2C_DEBUG
-                       printk(KERN_DEBUG "go7007-usb: i2c write %d "
-                                       "bytes on %02x\n", msgs[i].len,
-                                       msgs[i].addr);
+                       pr_debug("i2c write %d bytes on %02x\n",
+                                       msgs[i].len, msgs[i].addr);
 #endif
                        buf[0] = 0x00;
                        buf[1] = msgs[i].len + 1;
@@ -1082,7 +1059,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
        char *name;
        int video_pipe, i, v_urb_len;
 
-       printk(KERN_DEBUG "go7007-usb: probing new GO7007 USB board\n");
+       pr_debug("probing new GO7007 USB board\n");
 
        switch (id->driver_info) {
        case GO7007_BOARDID_MATRIX_II:
@@ -1122,14 +1099,13 @@ static int go7007_usb_probe(struct usb_interface *intf,
                board = &board_px_tv402u;
                break;
        case GO7007_BOARDID_LIFEVIEW_LR192:
-               printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra "
-                               "is not supported.  Sorry!\n");
+               pr_err("The Lifeview TV Walker Ultra is not supported. Sorry!\n");
                return -ENODEV;
                name = "Lifeview TV Walker Ultra";
                board = &board_lifeview_lr192;
                break;
        case GO7007_BOARDID_SENSORAY_2250:
-               printk(KERN_INFO "Sensoray 2250 found\n");
+               pr_info("Sensoray 2250 found\n");
                name = "Sensoray 2250/2251";
                board = &board_sensoray_2250;
                break;
@@ -1138,7 +1114,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
                board = &board_ads_usbav_709;
                break;
        default:
-               printk(KERN_ERR "go7007-usb: unknown board ID %d!\n",
+               pr_err("unknown board ID %d!\n",
                                (unsigned int)id->driver_info);
                return -ENODEV;
        }
@@ -1197,8 +1173,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
                go->i2c_adapter.dev.parent = go->dev;
                i2c_set_adapdata(&go->i2c_adapter, go);
                if (i2c_add_adapter(&go->i2c_adapter) < 0) {
-                       printk(KERN_ERR
-                               "go7007-usb: error: i2c_add_adapter failed\n");
+                       pr_err("error: i2c_add_adapter failed\n");
                        goto allocfail;
                }
                go->i2c_adapter_online = 1;
@@ -1248,8 +1223,9 @@ static int go7007_usb_probe(struct usb_interface *intf,
        /* Probe the tuner model on the TV402U */
        if (go->board_id == GO7007_BOARDID_PX_TV402U) {
                /* Board strapping indicates tuner model */
-               if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3, 1) < 0) {
-                       printk(KERN_ERR "go7007-usb: GPIO read failed!\n");
+               if (go7007_usb_vendor_request(go, 0x41, 0, 0, go->usb_buf, 3,
+                                       1) < 0) {
+                       pr_err("GPIO read failed!\n");
                        goto allocfail;
                }
                switch (go->usb_buf[0] >> 6) {
@@ -1273,15 +1249,14 @@ static int go7007_usb_probe(struct usb_interface *intf,
                                        sizeof(go->name));
                        break;
                default:
-                       printk(KERN_DEBUG "go7007-usb: unable to detect "
-                                               "tuner type!\n");
+                       pr_debug("unable to detect tuner type!\n");
                        break;
                }
                /* Configure tuner mode selection inputs connected
                 * to the EZ-USB GPIO output pins */
                if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
                                        NULL, 0, 0) < 0) {
-                       printk(KERN_ERR "go7007-usb: GPIO write failed!\n");
+                       pr_err("GPIO write failed!\n");
                        goto allocfail;
                }
        }
@@ -1290,11 +1265,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
         * a USB1.1 port.  There will be silent corruption of the stream. */
        if ((board->flags & GO7007_USB_EZUSB) &&
                        usbdev->speed != USB_SPEED_HIGH)
-               printk(KERN_ERR "go7007-usb: *** WARNING ***  This device "
-                               "must be connected to a USB 2.0 port!  "
-                               "Attempting to capture video through a USB 1.1 "
-                               "port will result in stream corruption, even "
-                               "at low bitrates!\n");
+               pr_err("*** WARNING ***  This device must be connected to a USB 2.0 port! Attempting to capture video through a USB 1.1 port will result in stream corruption, even at low bitrates!\n");
 
        /* Allocate the URBs and buffers for receiving the video stream */
        if (board->flags & GO7007_USB_EZUSB) {
index fa31ee7dd6a9e5f742dafb117426cd801d9318e2..fbbdce4c119f71cab122bde5c203bb03b9ee43de 100644 (file)
@@ -132,7 +132,7 @@ int init_module(void)
        atir_driver.minor       = -1;
        atir_driver.code_length = 8;
        atir_driver.sample_rate = 10;
-       atir_driver.data        = 0;
+       atir_driver.data        = NULL;
        atir_driver.add_to_buf  = atir_add_to_buf;
        atir_driver.set_use_inc = atir_set_use_inc;
        atir_driver.set_use_dec = atir_set_use_dec;
@@ -159,7 +159,7 @@ void cleanup_module(void)
 static int atir_init_start(void)
 {
        pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400);
-       if (pci_addr_lin == 0) {
+       if (!pci_addr_lin) {
                pr_info("pci mem must be mapped\n");
                return 0;
        }
diff --git a/drivers/staging/mt29f_spinand/Kconfig b/drivers/staging/mt29f_spinand/Kconfig
new file mode 100644 (file)
index 0000000..4031748
--- /dev/null
@@ -0,0 +1,16 @@
+config MTD_SPINAND_MT29F
+       tristate "SPINAND Device Support for Micron"
+       depends on MTD_NAND && SPI
+       help
+         This enables support for accessing Micron SPI NAND flash
+         devices.
+         If you have Micron SPI NAND chip say yes.
+
+         If unsure, say no here.
+
+config MTD_SPINAND_ONDIEECC
+       bool "Use SPINAND internal ECC"
+       depends on MTD_SPINAND_MT29F
+       help
+         Internel ECC.
+         Enables Hardware ECC support for Micron SPI NAND.
diff --git a/drivers/staging/mt29f_spinand/Makefile b/drivers/staging/mt29f_spinand/Makefile
new file mode 100644 (file)
index 0000000..e47af0f
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand.o
diff --git a/drivers/staging/mt29f_spinand/TODO b/drivers/staging/mt29f_spinand/TODO
new file mode 100644 (file)
index 0000000..a2209b7
--- /dev/null
@@ -0,0 +1,13 @@
+TODO:
+       - Tested on XLP platform, needs to be tested on other platforms.
+       - Checkpatch.pl cleanups
+       - Sparce fixes.
+       - Clean up coding style to meet kernel standard.
+
+Please send patches
+To:
+Kamlakant Patel <kamlakant.patel@broadcom.com>
+Cc:
+Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Mona Anonuevo <manonuevo@micron.com>
+linux-mtd@lists.infradead.org
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c
new file mode 100644 (file)
index 0000000..51dbc13
--- /dev/null
@@ -0,0 +1,947 @@
+/*
+ * Copyright (c) 2003-2013 Broadcom Corporation
+ *
+ * Copyright (c) 2009-2010 Micron Technology, Inc.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/spi/spi.h>
+
+#include "mt29f_spinand.h"
+
+#define BUFSIZE (10 * 64 * 2048)
+#define CACHE_BUF 2112
+/*
+ * OOB area specification layout:  Total 32 available free bytes.
+ */
+
+static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd)
+{
+       struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+       struct spinand_state *state = (struct spinand_state *)info->priv;
+
+       return state;
+}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+static int enable_hw_ecc;
+static int enable_read_hw_ecc;
+
+static struct nand_ecclayout spinand_oob_64 = {
+       .eccbytes = 24,
+       .eccpos = {
+               1, 2, 3, 4, 5, 6,
+               17, 18, 19, 20, 21, 22,
+               33, 34, 35, 36, 37, 38,
+               49, 50, 51, 52, 53, 54, },
+       .oobavail = 32,
+       .oobfree = {
+               {.offset = 8,
+                       .length = 8},
+               {.offset = 24,
+                       .length = 8},
+               {.offset = 40,
+                       .length = 8},
+               {.offset = 56,
+                       .length = 8},
+       }
+};
+#endif
+
+/*
+ * spinand_cmd - to process a command to send to the SPI Nand
+ * Description:
+ *    Set up the command buffer to send to the SPI controller.
+ *    The command buffer has to initialized to 0.
+ */
+
+static int spinand_cmd(struct spi_device *spi, struct spinand_cmd *cmd)
+{
+       struct spi_message message;
+       struct spi_transfer x[4];
+       u8 dummy = 0xff;
+
+       spi_message_init(&message);
+       memset(x, 0, sizeof(x));
+
+       x[0].len = 1;
+       x[0].tx_buf = &cmd->cmd;
+       spi_message_add_tail(&x[0], &message);
+
+       if (cmd->n_addr) {
+               x[1].len = cmd->n_addr;
+               x[1].tx_buf = cmd->addr;
+               spi_message_add_tail(&x[1], &message);
+       }
+
+       if (cmd->n_dummy) {
+               x[2].len = cmd->n_dummy;
+               x[2].tx_buf = &dummy;
+               spi_message_add_tail(&x[2], &message);
+       }
+
+       if (cmd->n_tx) {
+               x[3].len = cmd->n_tx;
+               x[3].tx_buf = cmd->tx_buf;
+               spi_message_add_tail(&x[3], &message);
+       }
+
+       if (cmd->n_rx) {
+               x[3].len = cmd->n_rx;
+               x[3].rx_buf = cmd->rx_buf;
+               spi_message_add_tail(&x[3], &message);
+       }
+
+       return spi_sync(spi, &message);
+}
+
+/*
+ * spinand_read_id- Read SPI Nand ID
+ * Description:
+ *    Read ID: read two ID bytes from the SPI Nand device
+ */
+static int spinand_read_id(struct spi_device *spi_nand, u8 *id)
+{
+       int retval;
+       u8 nand_id[3];
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_READ_ID;
+       cmd.n_rx = 3;
+       cmd.rx_buf = &nand_id[0];
+
+       retval = spinand_cmd(spi_nand, &cmd);
+       if (retval < 0) {
+               dev_err(&spi_nand->dev, "error %d reading id\n", retval);
+               return retval;
+       }
+       id[0] = nand_id[1];
+       id[1] = nand_id[2];
+       return retval;
+}
+
+/*
+ * spinand_read_status- send command 0xf to the SPI Nand status register
+ * Description:
+ *    After read, write, or erase, the Nand device is expected to set the
+ *    busy status.
+ *    This function is to allow reading the status of the command: read,
+ *    write, and erase.
+ *    Once the status turns to be ready, the other status bits also are
+ *    valid status bits.
+ */
+static int spinand_read_status(struct spi_device *spi_nand, uint8_t *status)
+{
+       struct spinand_cmd cmd = {0};
+       int ret;
+
+       cmd.cmd = CMD_READ_REG;
+       cmd.n_addr = 1;
+       cmd.addr[0] = REG_STATUS;
+       cmd.n_rx = 1;
+       cmd.rx_buf = status;
+
+       ret = spinand_cmd(spi_nand, &cmd);
+       if (ret < 0)
+               dev_err(&spi_nand->dev, "err: %d read status register\n", ret);
+
+       return ret;
+}
+
+#define MAX_WAIT_JIFFIES  (40 * HZ)
+static int wait_till_ready(struct spi_device *spi_nand)
+{
+       unsigned long deadline;
+       int retval;
+       u8 stat = 0;
+
+       deadline = jiffies + MAX_WAIT_JIFFIES;
+       do {
+               retval = spinand_read_status(spi_nand, &stat);
+               if (retval < 0)
+                       return -1;
+               else if (!(stat & 0x1))
+                       break;
+
+               cond_resched();
+       } while (!time_after_eq(jiffies, deadline));
+
+       if ((stat & 0x1) == 0)
+               return 0;
+
+       return -1;
+}
+/**
+ * spinand_get_otp- send command 0xf to read the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_get_otp(struct spi_device *spi_nand, u8 *otp)
+{
+       struct spinand_cmd cmd = {0};
+       int retval;
+
+       cmd.cmd = CMD_READ_REG;
+       cmd.n_addr = 1;
+       cmd.addr[0] = REG_OTP;
+       cmd.n_rx = 1;
+       cmd.rx_buf = otp;
+
+       retval = spinand_cmd(spi_nand, &cmd);
+       if (retval < 0)
+               dev_err(&spi_nand->dev, "error %d get otp\n", retval);
+       return retval;
+}
+
+/**
+ * spinand_set_otp- send command 0x1f to write the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_set_otp(struct spi_device *spi_nand, u8 *otp)
+{
+       int retval;
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_WRITE_REG,
+       cmd.n_addr = 1,
+       cmd.addr[0] = REG_OTP,
+       cmd.n_tx = 1,
+       cmd.tx_buf = otp,
+
+       retval = spinand_cmd(spi_nand, &cmd);
+       if (retval < 0)
+               dev_err(&spi_nand->dev, "error %d set otp\n", retval);
+
+       return retval;
+}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+/**
+ * spinand_enable_ecc- send command 0x1f to write the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_enable_ecc(struct spi_device *spi_nand)
+{
+       int retval;
+       u8 otp = 0;
+
+       retval = spinand_get_otp(spi_nand, &otp);
+       if (retval < 0)
+               return retval;
+
+       if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) {
+               return 0;
+       } else {
+               otp |= OTP_ECC_MASK;
+               retval = spinand_set_otp(spi_nand, &otp);
+               if (retval < 0)
+                       return retval;
+               return spinand_get_otp(spi_nand, &otp);
+       }
+}
+#endif
+
+static int spinand_disable_ecc(struct spi_device *spi_nand)
+{
+       int retval;
+       u8 otp = 0;
+
+       retval = spinand_get_otp(spi_nand, &otp);
+       if (retval < 0)
+               return retval;
+
+       if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) {
+               otp &= ~OTP_ECC_MASK;
+               retval = spinand_set_otp(spi_nand, &otp);
+               if (retval < 0)
+                       return retval;
+               return spinand_get_otp(spi_nand, &otp);
+       } else
+               return 0;
+}
+
+/**
+ * spinand_write_enable- send command 0x06 to enable write or erase the
+ * Nand cells
+ * Description:
+ *   Before write and erase the Nand cells, the write enable has to be set.
+ *   After the write or erase, the write enable bit is automatically
+ *   cleared (status register bit 2)
+ *   Set the bit 2 of the status register has the same effect
+ */
+static int spinand_write_enable(struct spi_device *spi_nand)
+{
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_WR_ENABLE;
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+static int spinand_read_page_to_cache(struct spi_device *spi_nand, u16 page_id)
+{
+       struct spinand_cmd cmd = {0};
+       u16 row;
+
+       row = page_id;
+       cmd.cmd = CMD_READ;
+       cmd.n_addr = 3;
+       cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+       cmd.addr[2] = (u8)(row & 0x00ff);
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/*
+ * spinand_read_from_cache- send command 0x03 to read out the data from the
+ * cache register(2112 bytes max)
+ * Description:
+ *   The read can specify 1 to 2112 bytes of data read at the corresponding
+ *   locations.
+ *   No tRd delay.
+ */
+static int spinand_read_from_cache(struct spi_device *spi_nand, u16 page_id,
+               u16 byte_id, u16 len, u8 *rbuf)
+{
+       struct spinand_cmd cmd = {0};
+       u16 column;
+
+       column = byte_id;
+       cmd.cmd = CMD_READ_RDM;
+       cmd.n_addr = 3;
+       cmd.addr[0] = (u8)((column & 0xff00) >> 8);
+       cmd.addr[0] |= (u8)(((page_id >> 6) & 0x1) << 4);
+       cmd.addr[1] = (u8)(column & 0x00ff);
+       cmd.addr[2] = (u8)(0xff);
+       cmd.n_dummy = 0;
+       cmd.n_rx = len;
+       cmd.rx_buf = rbuf;
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/*
+ * spinand_read_page-to read a page with:
+ * @page_id: the physical page number
+ * @offset:  the location from 0 to 2111
+ * @len:     number of bytes to read
+ * @rbuf:    read buffer to hold @len bytes
+ *
+ * Description:
+ *   The read includes two commands to the Nand: 0x13 and 0x03 commands
+ *   Poll to read status to wait for tRD time.
+ */
+static int spinand_read_page(struct spi_device *spi_nand, u16 page_id,
+               u16 offset, u16 len, u8 *rbuf)
+{
+       int ret;
+       u8 status = 0;
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       if (enable_read_hw_ecc) {
+               if (spinand_enable_ecc(spi_nand) < 0)
+                       dev_err(&spi_nand->dev, "enable HW ECC failed!");
+       }
+#endif
+       ret = spinand_read_page_to_cache(spi_nand, page_id);
+       if (ret < 0)
+               return ret;
+
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "WAIT timedout!!!\n");
+
+       while (1) {
+               ret = spinand_read_status(spi_nand, &status);
+               if (ret < 0) {
+                       dev_err(&spi_nand->dev,
+                                       "err %d read status register\n", ret);
+                       return ret;
+               }
+
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
+                               dev_err(&spi_nand->dev, "ecc error, page=%d\n",
+                                               page_id);
+                               return 0;
+                       }
+                       break;
+               }
+       }
+
+       ret = spinand_read_from_cache(spi_nand, page_id, offset, len, rbuf);
+       if (ret < 0) {
+               dev_err(&spi_nand->dev, "read from cache failed!!\n");
+               return ret;
+       }
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       if (enable_read_hw_ecc) {
+               ret = spinand_disable_ecc(spi_nand);
+               if (ret < 0) {
+                       dev_err(&spi_nand->dev, "disable ecc failed!!\n");
+                       return ret;
+               }
+               enable_read_hw_ecc = 0;
+       }
+#endif
+       return ret;
+}
+
+/*
+ * spinand_program_data_to_cache--to write a page to cache with:
+ * @byte_id: the location to write to the cache
+ * @len:     number of bytes to write
+ * @rbuf:    read buffer to hold @len bytes
+ *
+ * Description:
+ *   The write command used here is 0x84--indicating that the cache is
+ *   not cleared first.
+ *   Since it is writing the data to cache, there is no tPROG time.
+ */
+static int spinand_program_data_to_cache(struct spi_device *spi_nand,
+               u16 page_id, u16 byte_id, u16 len, u8 *wbuf)
+{
+       struct spinand_cmd cmd = {0};
+       u16 column;
+
+       column = byte_id;
+       cmd.cmd = CMD_PROG_PAGE_CLRCACHE;
+       cmd.n_addr = 2;
+       cmd.addr[0] = (u8)((column & 0xff00) >> 8);
+       cmd.addr[0] |= (u8)(((page_id >> 6) & 0x1) << 4);
+       cmd.addr[1] = (u8)(column & 0x00ff);
+       cmd.n_tx = len;
+       cmd.tx_buf = wbuf;
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_program_execute--to write a page from cache to the Nand array with
+ * @page_id: the physical page location to write the page.
+ *
+ * Description:
+ *   The write command used here is 0x10--indicating the cache is writing to
+ *   the Nand array.
+ *   Need to wait for tPROG time to finish the transaction.
+ */
+static int spinand_program_execute(struct spi_device *spi_nand, u16 page_id)
+{
+       struct spinand_cmd cmd = {0};
+       u16 row;
+
+       row = page_id;
+       cmd.cmd = CMD_PROG_PAGE_EXC;
+       cmd.n_addr = 3;
+       cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+       cmd.addr[2] = (u8)(row & 0x00ff);
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_program_page--to write a page with:
+ * @page_id: the physical page location to write the page.
+ * @offset:  the location from the cache starting from 0 to 2111
+ * @len:     the number of bytes to write
+ * @wbuf:    the buffer to hold the number of bytes
+ *
+ * Description:
+ *   The commands used here are 0x06, 0x84, and 0x10--indicating that
+ *   the write enable is first sent, the write cache command, and the
+ *   write execute command.
+ *   Poll to wait for the tPROG time to finish the transaction.
+ */
+static int spinand_program_page(struct spi_device *spi_nand,
+               u16 page_id, u16 offset, u16 len, u8 *buf)
+{
+       int retval;
+       u8 status = 0;
+       uint8_t *wbuf;
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       unsigned int i, j;
+
+       enable_read_hw_ecc = 0;
+       wbuf = devm_kzalloc(&spi_nand->dev, CACHE_BUF, GFP_KERNEL);
+       spinand_read_page(spi_nand, page_id, 0, CACHE_BUF, wbuf);
+
+       for (i = offset, j = 0; i < len; i++, j++)
+               wbuf[i] &= buf[j];
+
+       if (enable_hw_ecc) {
+               retval = spinand_enable_ecc(spi_nand);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev, "enable ecc failed!!\n");
+                       return retval;
+               }
+       }
+#else
+       wbuf = buf;
+#endif
+       retval = spinand_write_enable(spi_nand);
+       if (retval < 0) {
+               dev_err(&spi_nand->dev, "write enable failed!!\n");
+               return retval;
+       }
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "wait timedout!!!\n");
+
+       retval = spinand_program_data_to_cache(spi_nand, page_id,
+                       offset, len, wbuf);
+       if (retval < 0)
+               return retval;
+       retval = spinand_program_execute(spi_nand, page_id);
+       if (retval < 0)
+               return retval;
+       while (1) {
+               retval = spinand_read_status(spi_nand, &status);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev,
+                                       "error %d reading status register\n",
+                                       retval);
+                       return retval;
+               }
+
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_P_FAIL_MASK) == STATUS_P_FAIL) {
+                               dev_err(&spi_nand->dev,
+                                       "program error, page %d\n", page_id);
+                               return -1;
+                       } else
+                               break;
+               }
+       }
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       if (enable_hw_ecc) {
+               retval = spinand_disable_ecc(spi_nand);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev, "disable ecc failed!!\n");
+                       return retval;
+               }
+               enable_hw_ecc = 0;
+       }
+#endif
+
+       return 0;
+}
+
+/**
+ * spinand_erase_block_erase--to erase a page with:
+ * @block_id: the physical block location to erase.
+ *
+ * Description:
+ *   The command used here is 0xd8--indicating an erase command to erase
+ *   one block--64 pages
+ *   Need to wait for tERS.
+ */
+static int spinand_erase_block_erase(struct spi_device *spi_nand, u16 block_id)
+{
+       struct spinand_cmd cmd = {0};
+       u16 row;
+
+       row = block_id;
+       cmd.cmd = CMD_ERASE_BLK;
+       cmd.n_addr = 3;
+       cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+       cmd.addr[2] = (u8)(row & 0x00ff);
+
+       return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_erase_block--to erase a page with:
+ * @block_id: the physical block location to erase.
+ *
+ * Description:
+ *   The commands used here are 0x06 and 0xd8--indicating an erase
+ *   command to erase one block--64 pages
+ *   It will first to enable the write enable bit (0x06 command),
+ *   and then send the 0xd8 erase command
+ *   Poll to wait for the tERS time to complete the tranaction.
+ */
+static int spinand_erase_block(struct spi_device *spi_nand, u16 block_id)
+{
+       int retval;
+       u8 status = 0;
+
+       retval = spinand_write_enable(spi_nand);
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "wait timedout!!!\n");
+
+       retval = spinand_erase_block_erase(spi_nand, block_id);
+       while (1) {
+               retval = spinand_read_status(spi_nand, &status);
+               if (retval < 0) {
+                       dev_err(&spi_nand->dev,
+                                       "error %d reading status register\n",
+                                       (int) retval);
+                       return retval;
+               }
+
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_E_FAIL_MASK) == STATUS_E_FAIL) {
+                               dev_err(&spi_nand->dev,
+                                       "erase error, block %d\n", block_id);
+                               return -1;
+                       } else
+                               break;
+               }
+       }
+       return 0;
+}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+static int spinand_write_page_hwecc(struct mtd_info *mtd,
+               struct nand_chip *chip, const uint8_t *buf, int oob_required)
+{
+       const uint8_t *p = buf;
+       int eccsize = chip->ecc.size;
+       int eccsteps = chip->ecc.steps;
+
+       enable_hw_ecc = 1;
+       chip->write_buf(mtd, p, eccsize * eccsteps);
+       return 0;
+}
+
+static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+               uint8_t *buf, int oob_required, int page)
+{
+       u8 retval, status;
+       uint8_t *p = buf;
+       int eccsize = chip->ecc.size;
+       int eccsteps = chip->ecc.steps;
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+
+       enable_read_hw_ecc = 1;
+
+       chip->read_buf(mtd, p, eccsize * eccsteps);
+       if (oob_required)
+               chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       while (1) {
+               retval = spinand_read_status(info->spi, &status);
+               if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+                       if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
+                               pr_info("spinand: ECC error\n");
+                               mtd->ecc_stats.failed++;
+                       } else if ((status & STATUS_ECC_MASK) ==
+                                       STATUS_ECC_1BIT_CORRECTED)
+                               mtd->ecc_stats.corrected++;
+                       break;
+               }
+       }
+       return 0;
+
+}
+#endif
+
+static void spinand_select_chip(struct mtd_info *mtd, int dev)
+{
+}
+
+static uint8_t spinand_read_byte(struct mtd_info *mtd)
+{
+       struct spinand_state *state = mtd_to_state(mtd);
+       u8 data;
+
+       data = state->buf[state->buf_ptr];
+       state->buf_ptr++;
+       return data;
+}
+
+
+static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip)
+{
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+
+       unsigned long timeo = jiffies;
+       int retval, state = chip->state;
+       u8 status;
+
+       if (state == FL_ERASING)
+               timeo += (HZ * 400) / 1000;
+       else
+               timeo += (HZ * 20) / 1000;
+
+       while (time_before(jiffies, timeo)) {
+               retval = spinand_read_status(info->spi, &status);
+               if ((status & STATUS_OIP_MASK) == STATUS_READY)
+                       return 0;
+
+               cond_resched();
+       }
+       return 0;
+}
+
+static void spinand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+
+       struct spinand_state *state = mtd_to_state(mtd);
+       memcpy(state->buf + state->buf_ptr, buf, len);
+       state->buf_ptr += len;
+}
+
+static void spinand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+       struct spinand_state *state = mtd_to_state(mtd);
+       memcpy(buf, state->buf + state->buf_ptr, len);
+       state->buf_ptr += len;
+}
+
+/*
+ * spinand_reset- send RESET command "0xff" to the Nand device.
+ */
+static void spinand_reset(struct spi_device *spi_nand)
+{
+       struct spinand_cmd cmd = {0};
+
+       cmd.cmd = CMD_RESET;
+
+       if (spinand_cmd(spi_nand, &cmd) < 0)
+               pr_info("spinand reset failed!\n");
+
+       /* elapse 1ms before issuing any other command */
+       udelay(1000);
+
+       if (wait_till_ready(spi_nand))
+               dev_err(&spi_nand->dev, "wait timedout!\n");
+}
+
+static void spinand_cmdfunc(struct mtd_info *mtd, unsigned int command,
+               int column, int page)
+{
+       struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+       struct spinand_info *info = (struct spinand_info *)chip->priv;
+       struct spinand_state *state = (struct spinand_state *)info->priv;
+
+       switch (command) {
+       /*
+        * READ0 - read in first  0x800 bytes
+        */
+       case NAND_CMD_READ1:
+       case NAND_CMD_READ0:
+               state->buf_ptr = 0;
+               spinand_read_page(info->spi, page, 0x0, 0x840, state->buf);
+               break;
+       /* READOOB reads only the OOB because no ECC is performed. */
+       case NAND_CMD_READOOB:
+               state->buf_ptr = 0;
+               spinand_read_page(info->spi, page, 0x800, 0x40, state->buf);
+               break;
+       case NAND_CMD_RNDOUT:
+               state->buf_ptr = column;
+               break;
+       case NAND_CMD_READID:
+               state->buf_ptr = 0;
+               spinand_read_id(info->spi, (u8 *)state->buf);
+               break;
+       case NAND_CMD_PARAM:
+               state->buf_ptr = 0;
+               break;
+       /* ERASE1 stores the block and page address */
+       case NAND_CMD_ERASE1:
+               spinand_erase_block(info->spi, page);
+               break;
+       /* ERASE2 uses the block and page address from ERASE1 */
+       case NAND_CMD_ERASE2:
+               break;
+       /* SEQIN sets up the addr buffer and all registers except the length */
+       case NAND_CMD_SEQIN:
+               state->col = column;
+               state->row = page;
+               state->buf_ptr = 0;
+               break;
+       /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
+       case NAND_CMD_PAGEPROG:
+               spinand_program_page(info->spi, state->row, state->col,
+                               state->buf_ptr, state->buf);
+               break;
+       case NAND_CMD_STATUS:
+               spinand_get_otp(info->spi, state->buf);
+               if (!(state->buf[0] & 0x80))
+                       state->buf[0] = 0x80;
+               state->buf_ptr = 0;
+               break;
+       /* RESET command */
+       case NAND_CMD_RESET:
+               if (wait_till_ready(info->spi))
+                       dev_err(&info->spi->dev, "WAIT timedout!!!\n");
+               /* a minimum of 250us must elapse before issuing RESET cmd*/
+               udelay(250);
+               spinand_reset(info->spi);
+               break;
+       default:
+               dev_err(&mtd->dev, "Unknown CMD: 0x%x\n", command);
+       }
+}
+
+/**
+ * spinand_lock_block- send write register 0x1f command to the Nand device
+ *
+ * Description:
+ *    After power up, all the Nand blocks are locked.  This function allows
+ *    one to unlock the blocks, and so it can be written or erased.
+ */
+static int spinand_lock_block(struct spi_device *spi_nand, u8 lock)
+{
+       struct spinand_cmd cmd = {0};
+       int ret;
+       u8 otp = 0;
+
+       ret = spinand_get_otp(spi_nand, &otp);
+
+       cmd.cmd = CMD_WRITE_REG;
+       cmd.n_addr = 1;
+       cmd.addr[0] = REG_BLOCK_LOCK;
+       cmd.n_tx = 1;
+       cmd.tx_buf = &lock;
+
+       ret = spinand_cmd(spi_nand, &cmd);
+       if (ret < 0)
+               dev_err(&spi_nand->dev, "error %d lock block\n", ret);
+
+       return ret;
+}
+/*
+ * spinand_probe - [spinand Interface]
+ * @spi_nand: registered device driver.
+ *
+ * Description:
+ *   To set up the device driver parameters to make the device available.
+ */
+static int spinand_probe(struct spi_device *spi_nand)
+{
+       struct mtd_info *mtd;
+       struct nand_chip *chip;
+       struct spinand_info *info;
+       struct spinand_state *state;
+       struct mtd_part_parser_data ppdata;
+
+       info  = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_info),
+                       GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       info->spi = spi_nand;
+
+       spinand_lock_block(spi_nand, BL_ALL_UNLOCKED);
+
+       state = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_state),
+                       GFP_KERNEL);
+       if (!state)
+               return -ENOMEM;
+
+       info->priv      = state;
+       state->buf_ptr  = 0;
+       state->buf      = devm_kzalloc(&spi_nand->dev, BUFSIZE, GFP_KERNEL);
+       if (!state->buf)
+               return -ENOMEM;
+
+       chip = devm_kzalloc(&spi_nand->dev, sizeof(struct nand_chip),
+                       GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+       chip->ecc.mode  = NAND_ECC_HW;
+       chip->ecc.size  = 0x200;
+       chip->ecc.bytes = 0x6;
+       chip->ecc.steps = 0x4;
+
+       chip->ecc.strength = 1;
+       chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
+       chip->ecc.layout = &spinand_oob_64;
+       chip->ecc.read_page = spinand_read_page_hwecc;
+       chip->ecc.write_page = spinand_write_page_hwecc;
+#else
+       chip->ecc.mode  = NAND_ECC_SOFT;
+       if (spinand_disable_ecc(spi_nand) < 0)
+               pr_info("%s: disable ecc failed!\n", __func__);
+#endif
+
+       chip->priv      = info;
+       chip->read_buf  = spinand_read_buf;
+       chip->write_buf = spinand_write_buf;
+       chip->read_byte = spinand_read_byte;
+       chip->cmdfunc   = spinand_cmdfunc;
+       chip->waitfunc  = spinand_wait;
+       chip->options   |= NAND_CACHEPRG;
+       chip->select_chip = spinand_select_chip;
+
+       mtd = devm_kzalloc(&spi_nand->dev, sizeof(struct mtd_info), GFP_KERNEL);
+       if (!mtd)
+               return -ENOMEM;
+
+       dev_set_drvdata(&spi_nand->dev, mtd);
+
+       mtd->priv = chip;
+       mtd->name = dev_name(&spi_nand->dev);
+       mtd->owner = THIS_MODULE;
+       mtd->oobsize = 64;
+
+       if (nand_scan(mtd, 1))
+               return -ENXIO;
+
+       ppdata.of_node = spi_nand->dev.of_node;
+       return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+}
+
+/*
+ * spinand_remove: Remove the device driver
+ * @spi: the spi device.
+ *
+ * Description:
+ *   To remove the device driver parameters and free up allocated memories.
+ */
+static int spinand_remove(struct spi_device *spi)
+{
+       mtd_device_unregister(dev_get_drvdata(&spi->dev));
+
+       return 0;
+}
+
+static const struct of_device_id spinand_dt[] = {
+       { .compatible = "spinand,mt29f", },
+};
+
+/*
+ * Device name structure description
+ */
+static struct spi_driver spinand_driver = {
+       .driver = {
+               .name           = "mt29f",
+               .bus            = &spi_bus_type,
+               .owner          = THIS_MODULE,
+               .of_match_table = spinand_dt,
+       },
+       .probe          = spinand_probe,
+       .remove         = spinand_remove,
+};
+
+module_spi_driver(spinand_driver);
+
+MODULE_DESCRIPTION("SPI NAND driver for Micron");
+MODULE_AUTHOR("Henry Pan <hspan@micron.com>, Kamlakant Patel <kamlakant.patel@broadcom.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.h b/drivers/staging/mt29f_spinand/mt29f_spinand.h
new file mode 100644 (file)
index 0000000..7f2c24d
--- /dev/null
@@ -0,0 +1,107 @@
+/*-
+ * Copyright 2013 Broadcom Corporation
+ *
+ * Copyright (c) 2009-2010 Micron Technology, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ * Henry Pan <hspan@micron.com>
+ *
+ * based on nand.h
+ */
+#ifndef __LINUX_MTD_SPI_NAND_H
+#define __LINUX_MTD_SPI_NAND_H
+
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/mtd/mtd.h>
+
+/* cmd */
+#define CMD_READ                       0x13
+#define CMD_READ_RDM                   0x03
+#define CMD_PROG_PAGE_CLRCACHE         0x02
+#define CMD_PROG_PAGE                  0x84
+#define CMD_PROG_PAGE_EXC              0x10
+#define CMD_ERASE_BLK                  0xd8
+#define CMD_WR_ENABLE                  0x06
+#define CMD_WR_DISABLE                 0x04
+#define CMD_READ_ID                    0x9f
+#define CMD_RESET                      0xff
+#define CMD_READ_REG                   0x0f
+#define CMD_WRITE_REG                  0x1f
+
+/* feature/ status reg */
+#define REG_BLOCK_LOCK                 0xa0
+#define REG_OTP                                0xb0
+#define REG_STATUS                     0xc0/* timing */
+
+/* status */
+#define STATUS_OIP_MASK                        0x01
+#define STATUS_READY                   (0 << 0)
+#define STATUS_BUSY                    (1 << 0)
+
+#define STATUS_E_FAIL_MASK             0x04
+#define STATUS_E_FAIL                  (1 << 2)
+
+#define STATUS_P_FAIL_MASK             0x08
+#define STATUS_P_FAIL                  (1 << 3)
+
+#define STATUS_ECC_MASK                        0x30
+#define STATUS_ECC_1BIT_CORRECTED      (1 << 4)
+#define STATUS_ECC_ERROR               (2 << 4)
+#define STATUS_ECC_RESERVED            (3 << 4)
+
+/*ECC enable defines*/
+#define OTP_ECC_MASK                   0x10
+#define OTP_ECC_OFF                    0
+#define OTP_ECC_ON                     1
+
+#define ECC_DISABLED
+#define ECC_IN_NAND
+#define ECC_SOFT
+
+/* block lock */
+#define BL_ALL_LOCKED      0x38
+#define BL_1_2_LOCKED      0x30
+#define BL_1_4_LOCKED      0x28
+#define BL_1_8_LOCKED      0x20
+#define BL_1_16_LOCKED     0x18
+#define BL_1_32_LOCKED     0x10
+#define BL_1_64_LOCKED     0x08
+#define BL_ALL_UNLOCKED    0
+
+struct spinand_info {
+       struct nand_ecclayout *ecclayout;
+       struct spi_device *spi;
+       void *priv;
+};
+
+struct spinand_state {
+       uint32_t        col;
+       uint32_t        row;
+       int             buf_ptr;
+       u8              *buf;
+};
+
+struct spinand_cmd {
+       u8              cmd;
+       u32             n_addr;         /* Number of address */
+       u8              addr[3];        /* Reg Offset */
+       u32             n_dummy;        /* Dummy use */
+       u32             n_tx;           /* Number of tx bytes */
+       u8              *tx_buf;        /* Tx buf */
+       u32             n_rx;           /* Number of rx bytes */
+       u8              *rx_buf;        /* Rx buf */
+};
+
+extern int spinand_mtd(struct mtd_info *mtd);
+extern void spinand_mtd_release(struct mtd_info *mtd);
+
+#endif /* __LINUX_MTD_SPI_NAND_H */
index 46eabd0e426ac9a1c5f06c0fbfcf1cf3e8fa6499..235d2b1ec593c4dfba7a83c4eb5fd0f578e0c5c4 100644 (file)
@@ -44,8 +44,8 @@
 #include <linux/platform_device.h>
 
 #include <asm/mipsregs.h>
-
-/* fmn.h - For FMN credit configuration and registering fmn_handler.
+/*
+ * fmn.h - For FMN credit configuration and registering fmn_handler.
  * FMN is communication mechanism that allows processing agents within
  * XLR/XLS to communicate each other.
  */
@@ -90,7 +90,8 @@ static inline struct sk_buff *mac_get_skb_back_ptr(void *addr)
 {
        struct sk_buff **back_ptr;
 
-       /* this function should be used only for newly allocated packets.
+       /*
+        * this function should be used only for newly allocated packets.
         * It assumes the first cacheline is for the back pointer related
         * book keeping info.
         */
@@ -102,7 +103,8 @@ static inline void mac_put_skb_back_ptr(struct sk_buff *skb)
 {
        struct sk_buff **back_ptr = (struct sk_buff **)skb->data;
 
-       /* this function should be used only for newly allocated packets.
+       /*
+        * this function should be used only for newly allocated packets.
         * It assumes the first cacheline is for the back pointer related
         * book keeping info.
         */
@@ -500,8 +502,10 @@ static void xlr_config_fifo_spill_area(struct xlr_net_priv *priv)
                        sizeof(u64));
 }
 
-/* Configure PDE to Round-Robin distribution of packets to the
- * available cpu */
+/*
+ * Configure PDE to Round-Robin distribution of packets to the
+ * available cpu
+ */
 static void xlr_config_pde(struct xlr_net_priv *priv)
 {
        int i = 0;
@@ -528,8 +532,10 @@ static void xlr_config_pde(struct xlr_net_priv *priv)
                        ((bkt_map >> 32) & 0xffffffff));
 }
 
-/* Setup the Message ring credits, bucket size and other
- * common configuration */
+/*
+ * Setup the Message ring credits, bucket size and other
+ * common configuration
+ */
 static void xlr_config_common(struct xlr_net_priv *priv)
 {
        struct xlr_fmn_info *gmac = priv->nd->gmac_fmn_info;
@@ -545,8 +551,10 @@ static void xlr_config_common(struct xlr_net_priv *priv)
                                bucket_size[i]);
        }
 
-       /* Setting non-core Credit counter register
-        * Distributing Gmac's credit to CPU's*/
+       /*
+        * Setting non-core Credit counter register
+        * Distributing Gmac's credit to CPU's
+        */
        for (i = 0; i < 8; i++) {
                for (j = 0; j < 8; j++)
                        xlr_nae_wreg(priv->base_addr,
@@ -593,7 +601,8 @@ static void xlr_config_translate_table(struct xlr_net_priv *priv)
        c1 = 3;
        c2 = 0;
        for (i = 0; i < 64; i++) {
-               /* On use_bkt set the b0, b1 are used, else
+               /*
+                * On use_bkt set the b0, b1 are used, else
                 * the 4 classes are used, here implemented
                 * a logic to distribute the packets to the
                 * buckets equally or based on the class
@@ -736,7 +745,8 @@ static int xlr_mii_read(struct mii_bus *bus, int phy_addr, int regnum)
        return ret;
 }
 
-/* XLR ports are RGMII. XLS ports are SGMII mostly except the port0,
+/*
+ * XLR ports are RGMII. XLS ports are SGMII mostly except the port0,
  * which can be configured either SGMII or RGMII, considered SGMII
  * by default, if board setup to RGMII the port_type need to set
  * accordingly.Serdes and PCS layer need to configured for SGMII
index f91d27e9d7c4b135e427e0e467709fefde7460b6..cea796633711976b116f5cddc46612be02ddec4d 100644 (file)
@@ -1096,4 +1096,4 @@ struct xlr_net_priv {
        u64 *class_3_spill;
 };
 
-extern void xlr_set_gmac_speed(struct xlr_net_priv *priv);
+void xlr_set_gmac_speed(struct xlr_net_priv *priv);
index 5a5c6397e74069000d66350c07fcc1fafafc01a6..3066ee2e753be3ed887d11b9615b41b78261b6bb 100644 (file)
@@ -802,7 +802,7 @@ static int tegra_nvec_probe(struct platform_device *pdev)
                unmute_speakers[] = { NVEC_OEM0, 0x10, 0x59, 0x95 },
                enable_event[7] = { NVEC_SYS, CNF_EVENT_REPORTING, true };
 
-       if(!pdev->dev.of_node) {
+       if (!pdev->dev.of_node) {
                dev_err(&pdev->dev, "must be instantiated using device tree\n");
                return -ENODEV;
        }
index 89df1ad8be308bfc7376f5a919f64a0f52d6fa9b..5588be395f2a7a967192d7f8ea478085865809a7 100644 (file)
@@ -1,3 +1 @@
-obj-${CONFIG_OCTEON_USB} := octeon-usb.o
-octeon-usb-y := octeon-hcd.o
-octeon-usb-y += cvmx-usb.o
+obj-${CONFIG_OCTEON_USB} := octeon-hcd.o
diff --git a/drivers/staging/octeon-usb/cvmx-usb.c b/drivers/staging/octeon-usb/cvmx-usb.c
deleted file mode 100644 (file)
index 45dfe94..0000000
+++ /dev/null
@@ -1,3158 +0,0 @@
-/***********************license start***************
- * 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.
- ***********************license end**************************************/
-
-
-/**
- * @file
- *
- * "cvmx-usb.c" defines a set of low level USB functions to help
- * developers create Octeon USB drivers for various operating
- * systems. These functions provide a generic API to the Octeon
- * USB blocks, hiding the internal hardware specific
- * operations.
- */
-#include <linux/delay.h>
-#include <asm/octeon/cvmx.h>
-#include <asm/octeon/octeon.h>
-#include <asm/octeon/cvmx-sysinfo.h>
-#include "cvmx-usbnx-defs.h"
-#include "cvmx-usbcx-defs.h"
-#include "cvmx-usb.h"
-#include <asm/octeon/cvmx-helper.h>
-#include <asm/octeon/cvmx-helper-board.h>
-
-#define CVMX_PREFETCH0(address) CVMX_PREFETCH(address, 0)
-#define CVMX_PREFETCH128(address) CVMX_PREFETCH(address, 128)
-// a normal prefetch
-#define CVMX_PREFETCH(address, offset) CVMX_PREFETCH_PREF0(address, offset)
-// normal prefetches that use the pref instruction
-#define CVMX_PREFETCH_PREFX(X, address, offset) asm volatile ("pref %[type], %[off](%[rbase])" : : [rbase] "d" (address), [off] "I" (offset), [type] "n" (X))
-#define CVMX_PREFETCH_PREF0(address, offset) CVMX_PREFETCH_PREFX(0, address, offset)
-#define CVMX_CLZ(result, input) asm ("clz %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
-
-#define MAX_RETRIES            3               /* Maximum number of times to retry failed transactions */
-#define MAX_PIPES              32              /* Maximum number of pipes that can be open at once */
-#define MAX_TRANSACTIONS       256             /* Maximum number of outstanding transactions across all pipes */
-#define MAX_CHANNELS           8               /* Maximum number of hardware channels supported by the USB block */
-#define MAX_USB_ADDRESS                127             /* The highest valid USB device address */
-#define MAX_USB_ENDPOINT       15              /* The highest valid USB endpoint number */
-#define MAX_USB_HUB_PORT       15              /* The highest valid port number on a hub */
-#define MAX_TRANSFER_BYTES     ((1<<19)-1)     /* 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_PACKETS   ((1<<10)-1)     /* The low level hardware can transfer a maximum of this number of packets in each transfer. The field is 10 bits wide */
-
-/*
- * These defines disable the normal read and write csr. This is so I can add
- * extra debug stuff to the usb specific version and I won't use the normal
- * version by mistake
- */
-#define cvmx_read_csr use_cvmx_usb_read_csr64_instead_of_cvmx_read_csr
-#define cvmx_write_csr use_cvmx_usb_write_csr64_instead_of_cvmx_write_csr
-
-enum cvmx_usb_transaction_flags {
-       __CVMX_USB_TRANSACTION_FLAGS_IN_USE = 1<<16,
-};
-
-enum {
-       USB_CLOCK_TYPE_REF_12,
-       USB_CLOCK_TYPE_REF_24,
-       USB_CLOCK_TYPE_REF_48,
-       USB_CLOCK_TYPE_CRYSTAL_12,
-};
-
-/**
- * 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.
- *
- * @prev:              Transaction before this one in the pipe.
- * @next:              Transaction after this one 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.
- * @callback:          User's callback function when complete.
- * @callback_data:     User's data.
- */
-struct cvmx_usb_transaction {
-       struct cvmx_usb_transaction *prev;
-       struct cvmx_usb_transaction *next;
-       enum cvmx_usb_transfer type;
-       enum cvmx_usb_transaction_flags flags;
-       uint64_t buffer;
-       int buffer_length;
-       uint64_t 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;
-       cvmx_usb_callback_func_t callback;
-       void *callback_data;
-};
-
-/**
- * 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.
- *
- * @prev:              Pipe before this one in the list
- * @next:              Pipe after this one in the list
- * @head:              The first pending transaction
- * @tail:              The last pending transaction
- * @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 cvmx_usb_pipe *prev;
-       struct cvmx_usb_pipe *next;
-       struct cvmx_usb_transaction *head;
-       struct cvmx_usb_transaction *tail;
-       uint64_t interval;
-       uint64_t 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;
-       uint16_t max_packet;
-       uint8_t device_addr;
-       uint8_t endpoint_num;
-       uint8_t hub_device_addr;
-       uint8_t hub_port;
-       uint8_t pid_toggle;
-       uint8_t channel;
-       int8_t split_sc_frame;
-};
-
-/**
- * struct cvmx_usb_pipe_list
- *
- * @head: Head of the list, or NULL if empty.
- * @tail: Tail if the list, or NULL if empty.
- */
-struct cvmx_usb_pipe_list {
-       struct cvmx_usb_pipe *head;
-       struct cvmx_usb_pipe *tail;
-};
-
-struct cvmx_usb_tx_fifo {
-       struct {
-               int channel;
-               int size;
-               uint64_t address;
-       } entry[MAX_CHANNELS+1];
-       int head;
-       int tail;
-};
-
-/**
- * struct cvmx_usb_internal_state - the state of the USB block
- *
- * 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.
- * free_transaction_head:  List of free transactions head.
- * free_transaction_tail:  List of free transactions tail.
- * pipe:                  Storage for pipes.
- * transaction:                   Storage for transactions.
- * callback:              User global callbacks.
- * callback_data:         User data for each callback.
- * indent:                Used by debug output to indent functions.
- * port_status:                   Last port status used for change notification.
- * free_pipes:            List of all pipes that are currently closed.
- * 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 cvmx_usb_internal_state {
-       int init_flags;
-       int index;
-       int idle_hardware_channels;
-       union cvmx_usbcx_hprt usbcx_hprt;
-       struct cvmx_usb_pipe *pipe_for_channel[MAX_CHANNELS];
-       struct cvmx_usb_transaction *free_transaction_head;
-       struct cvmx_usb_transaction *free_transaction_tail;
-       struct cvmx_usb_pipe pipe[MAX_PIPES];
-       struct cvmx_usb_transaction transaction[MAX_TRANSACTIONS];
-       cvmx_usb_callback_func_t callback[__CVMX_USB_CALLBACK_END];
-       void *callback_data[__CVMX_USB_CALLBACK_END];
-       int indent;
-       struct cvmx_usb_port_status port_status;
-       struct cvmx_usb_pipe_list free_pipes;
-       struct cvmx_usb_pipe_list idle_pipes;
-       struct cvmx_usb_pipe_list active_pipes[4];
-       uint64_t frame_number;
-       struct cvmx_usb_transaction *active_split;
-       struct cvmx_usb_tx_fifo periodic;
-       struct cvmx_usb_tx_fifo nonperiodic;
-};
-
-/* This macro spins on a field waiting for it to reach a value */
-#define CVMX_WAIT_FOR_FIELD32(address, type, field, op, value, timeout_usec)\
-       ({int result;                                                       \
-       do {                                                                \
-               uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \
-                       octeon_get_clock_rate() / 1000000;                  \
-               type c;                                                     \
-               while (1) {                                                 \
-                       c.u32 = __cvmx_usb_read_csr32(usb, address);        \
-                       if (c.s.field op (value)) {                         \
-                               result = 0;                                 \
-                               break;                                      \
-                       } else if (cvmx_get_cycle() > done) {               \
-                               result = -1;                                \
-                               break;                                      \
-                       } else                                              \
-                               cvmx_wait(100);                             \
-               }                                                           \
-       } while (0);                                                        \
-       result; })
-
-/*
- * This macro logically sets a single field in a CSR. It does the sequence
- * read, modify, and write
- */
-#define USB_SET_FIELD32(address, type, field, value)           \
-       do {                                                    \
-               type 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)
-
-static int octeon_usb_get_clock_type(void)
-{
-       switch (cvmx_sysinfo_get()->board_type) {
-       case CVMX_BOARD_TYPE_BBGW_REF:
-       case CVMX_BOARD_TYPE_LANAI2_A:
-       case CVMX_BOARD_TYPE_LANAI2_U:
-       case CVMX_BOARD_TYPE_LANAI2_G:
-       case CVMX_BOARD_TYPE_UBNT_E100:
-               return USB_CLOCK_TYPE_CRYSTAL_12;
-       }
-       return USB_CLOCK_TYPE_REF_48;
-}
-
-/**
- * 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 uint32_t __cvmx_usb_read_csr32(struct cvmx_usb_internal_state *usb,
-                                            uint64_t address)
-{
-       uint32_t result = cvmx_read64_uint32(address ^ 4);
-       return result;
-}
-
-
-/**
- * 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 cvmx_usb_internal_state *usb,
-                                         uint64_t address, uint32_t value)
-{
-       cvmx_write64_uint32(address ^ 4, value);
-       cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
-}
-
-
-/**
- * Read a USB 64bit CSR. It 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 uint64_t __cvmx_usb_read_csr64(struct cvmx_usb_internal_state *usb,
-                                            uint64_t address)
-{
-       uint64_t result = cvmx_read64_uint64(address);
-       return result;
-}
-
-
-/**
- * Write a USB 64bit CSR. It 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_csr64(struct cvmx_usb_internal_state *usb,
-                                         uint64_t address, uint64_t value)
-{
-       cvmx_write64_uint64(address, value);
-}
-
-/**
- * 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 cvmx_usb_internal_state *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 */
-       else
-               return 0; /* Data0 */
-}
-
-
-/**
- * Return the number of USB ports supported by this Octeon
- * chip. If the chip doesn't support USB, or is not supported
- * by this API, a zero will be returned. Most Octeon chips
- * support one usb port, but some support two ports.
- * cvmx_usb_initialize() must be called on independent
- * struct cvmx_usb_state.
- *
- * Returns: Number of port, zero if usb isn't supported
- */
-int cvmx_usb_get_num_ports(void)
-{
-       int arch_ports = 0;
-
-       if (OCTEON_IS_MODEL(OCTEON_CN56XX))
-               arch_ports = 1;
-       else if (OCTEON_IS_MODEL(OCTEON_CN52XX))
-               arch_ports = 2;
-       else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
-               arch_ports = 1;
-       else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
-               arch_ports = 1;
-       else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
-               arch_ports = 1;
-       else
-               arch_ports = 0;
-
-       return arch_ports;
-}
-
-
-/**
- * Allocate a usb transaction for use
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- *
- * Returns: Transaction or NULL
- */
-static inline struct cvmx_usb_transaction *__cvmx_usb_alloc_transaction(struct cvmx_usb_internal_state *usb)
-{
-       struct cvmx_usb_transaction *t;
-       t = usb->free_transaction_head;
-       if (t) {
-               usb->free_transaction_head = t->next;
-               if (!usb->free_transaction_head)
-                       usb->free_transaction_tail = NULL;
-       }
-       if (t) {
-               memset(t, 0, sizeof(*t));
-               t->flags = __CVMX_USB_TRANSACTION_FLAGS_IN_USE;
-       }
-       return t;
-}
-
-
-/**
- * Free a usb transaction
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @transaction:
- *              Transaction to free
- */
-static inline void __cvmx_usb_free_transaction(struct cvmx_usb_internal_state *usb,
-                                              struct cvmx_usb_transaction *transaction)
-{
-       transaction->flags = 0;
-       transaction->prev = NULL;
-       transaction->next = NULL;
-       if (usb->free_transaction_tail)
-               usb->free_transaction_tail->next = transaction;
-       else
-               usb->free_transaction_head = transaction;
-       usb->free_transaction_tail = transaction;
-}
-
-
-/**
- * Add a pipe to the tail of a list
- * @list:   List to add pipe to
- * @pipe:   Pipe to add
- */
-static inline void __cvmx_usb_append_pipe(struct cvmx_usb_pipe_list *list, struct cvmx_usb_pipe *pipe)
-{
-       pipe->next = NULL;
-       pipe->prev = list->tail;
-       if (list->tail)
-               list->tail->next = pipe;
-       else
-               list->head = pipe;
-       list->tail = pipe;
-}
-
-
-/**
- * Remove a pipe from a list
- * @list:   List to remove pipe from
- * @pipe:   Pipe to remove
- */
-static inline void __cvmx_usb_remove_pipe(struct cvmx_usb_pipe_list *list, struct cvmx_usb_pipe *pipe)
-{
-       if (list->head == pipe) {
-               list->head = pipe->next;
-               pipe->next = NULL;
-               if (list->head)
-                       list->head->prev = NULL;
-               else
-                       list->tail = NULL;
-       } else if (list->tail == pipe) {
-               list->tail = pipe->prev;
-               list->tail->next = NULL;
-               pipe->prev = NULL;
-       } else {
-               pipe->prev->next = pipe->next;
-               pipe->next->prev = pipe->prev;
-               pipe->prev = NULL;
-               pipe->next = NULL;
-       }
-}
-
-
-/**
- * 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.
- *
- * @state:      Pointer to an empty struct cvmx_usb_state
- *              that will be populated by the initialize call.
- *              This structure is then passed to all other USB
- *              functions.
- * @usb_port_number:
- *              Which Octeon USB port to initialize.
- * @flags:      Flags to control hardware initialization. See
- *              enum cvmx_usb_initialize_flags for the flag
- *              definitions. Some flags are mandatory.
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
-                       enum cvmx_usb_initialize_flags flags)
-{
-       union cvmx_usbnx_clk_ctl usbn_clk_ctl;
-       union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       usb->init_flags = flags;
-
-       /* Make sure that state is large enough to store the internal state */
-       if (sizeof(*state) < sizeof(*usb))
-               return -EINVAL;
-       /* At first allow 0-1 for the usb port number */
-       if ((usb_port_number < 0) || (usb_port_number > 1))
-               return -EINVAL;
-       /* For all chips except 52XX there is only one port */
-       if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
-               return -EINVAL;
-       /* Try to determine clock type automatically */
-       if ((flags & (CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI |
-                     CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND)) == 0) {
-               if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12)
-                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;  /* Only 12 MHZ crystals are supported */
-               else
-                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
-       }
-
-       if (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND) {
-               /* Check for auto ref clock frequency */
-               if (!(flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK))
-                       switch (octeon_usb_get_clock_type()) {
-                       case USB_CLOCK_TYPE_REF_12:
-                               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
-                               break;
-                       case USB_CLOCK_TYPE_REF_24:
-                               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
-                               break;
-                       case USB_CLOCK_TYPE_REF_48:
-                               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
-                               break;
-                       default:
-                               return -EINVAL;
-                               break;
-                       }
-       }
-
-       memset(usb, 0, sizeof(*usb));
-       usb->init_flags = flags;
-
-       /* Initialize the USB state structure */
-       {
-               int i;
-               usb->index = usb_port_number;
-
-               /* Initialize the transaction double linked list */
-               usb->free_transaction_head = NULL;
-               usb->free_transaction_tail = NULL;
-               for (i = 0; i < MAX_TRANSACTIONS; i++)
-                       __cvmx_usb_free_transaction(usb, usb->transaction + i);
-               for (i = 0; i < MAX_PIPES; i++)
-                       __cvmx_usb_append_pipe(&usb->free_pipes, usb->pipe + i);
-       }
-
-       /*
-        * 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_usb_read_csr64(usb, 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)) {
-                       usbn_clk_ctl.cn31xx.p_rclk  = 1; /* From CN31XX,CN30XX manual */
-                       usbn_clk_ctl.cn31xx.p_xenbn = 0;
-               } else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
-                       usbn_clk_ctl.cn56xx.p_rtype = 2; /* From CN56XX,CN50XX manual */
-               else
-                       usbn_clk_ctl.cn52xx.p_rtype = 1; /* From CN52XX manual */
-
-               switch (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)) {
-                       usbn_clk_ctl.cn31xx.p_rclk  = 1; /* From CN31XX,CN30XX manual */
-                       usbn_clk_ctl.cn31xx.p_xenbn = 1;
-               } else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
-                       usbn_clk_ctl.cn56xx.p_rtype = 0; /* From CN56XX,CN50XX manual */
-               else
-                       usbn_clk_ctl.cn52xx.p_rtype = 0; /* From CN52XX manual */
-
-               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
-        */
-       {
-               int divisor = (octeon_get_clock_rate()+125000000-1)/125000000;
-               if (divisor < 4)  /* Lower than 4 doesn't seem to work properly */
-                       divisor = 4;
-               usbn_clk_ctl.s.divide = divisor;
-               usbn_clk_ctl.s.divide2 = 0;
-       }
-       __cvmx_usb_write_csr64(usb, 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_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       /* 2e.  Wait 64 core-clock cycles for HCLK to stabilize */
-       cvmx_wait(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_usb_write_csr64(usb, 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_usb_read_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index));
-       usbn_usbp_ctl_status.s.ate_reset = 1;
-       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
-                              usbn_usbp_ctl_status.u64);
-       /* 6. Wait 10 cycles */
-       cvmx_wait(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_usb_write_csr64(usb, 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_usb_write_csr64(usb, 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_usb_write_csr64(usb, 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_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       /* 12. Proceed to USB core initialization */
-       usbn_clk_ctl.s.enable = 1;
-       __cvmx_usb_write_csr64(usb, 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
-        */
-       {
-               union cvmx_usbcx_gahbcfg usbcx_gahbcfg;
-               /* Due to an errata, CN31XX doesn't support DMA */
-               if (OCTEON_IS_MODEL(OCTEON_CN31XX))
-                       usb->init_flags |= CVMX_USB_INITIALIZE_FLAGS_NO_DMA;
-               usbcx_gahbcfg.u32 = 0;
-               usbcx_gahbcfg.s.dmaen = !(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA);
-               if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-                       usb->idle_hardware_channels = 0x1;  /* Only use one channel with non DMA */
-               else if (OCTEON_IS_MODEL(OCTEON_CN5XXX))
-                       usb->idle_hardware_channels = 0xf7; /* CN5XXX have an errata with channel 3 */
-               else
-                       usb->idle_hardware_channels = 0xff;
-               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
-        */
-       {
-               union cvmx_usbcx_gusbcfg usbcx_gusbcfg;
-               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
-        */
-       {
-               union cvmx_usbcx_gintmsk usbcx_gintmsk;
-               int channel;
-
-               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), union cvmx_usbcx_gintmsk,
-                               prtintmsk, 1);
-               USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk,
-                               disconnintmsk, 1);
-               /*
-                * 2. Program the USBC_HCFG register to select full-speed host
-                *    or high-speed host.
-                */
-               {
-                       union cvmx_usbcx_hcfg usbcx_hcfg;
-                       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);
-               }
-               /*
-                * 3. Program the port power bit to drive VBUS on the USB,
-                *    USBC_HPRT[PRTPWR] = 1
-                */
-               USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtpwr, 1);
-
-               /*
-                * Steps 4-15 from the manual are done later in the port enable
-                */
-       }
-
-       return 0;
-}
-
-
-/**
- * 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.
- *
- * @state: USB device state populated by
- *        cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_shutdown(struct cvmx_usb_state *state)
-{
-       union cvmx_usbnx_clk_ctl usbn_clk_ctl;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       /* Make sure all pipes are closed */
-       if (usb->idle_pipes.head ||
-               usb->active_pipes[CVMX_USB_TRANSFER_ISOCHRONOUS].head ||
-               usb->active_pipes[CVMX_USB_TRANSFER_INTERRUPT].head ||
-               usb->active_pipes[CVMX_USB_TRANSFER_CONTROL].head ||
-               usb->active_pipes[CVMX_USB_TRANSFER_BULK].head)
-               return -EBUSY;
-
-       /* Disable the clocks and put them in power on reset */
-       usbn_clk_ctl.u64 = __cvmx_usb_read_csr64(usb, 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_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
-                              usbn_clk_ctl.u64);
-       return 0;
-}
-
-
-/**
- * Enable a USB port. After this call succeeds, the USB port is
- * online and servicing requests.
- *
- * @state: USB device state populated by
- *        cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_enable(struct cvmx_usb_state *state)
-{
-       union cvmx_usbcx_ghwcfg3 usbcx_ghwcfg3;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
-
-       /*
-        * If the port is already enabled the just return. We don't need to do
-        * anything
-        */
-       if (usb->usbcx_hprt.s.prtena)
-               return 0;
-
-       /* If there is nothing plugged into the port then fail immediately */
-       if (!usb->usbcx_hprt.s.prtconnsts) {
-               return -ETIMEDOUT;
-       }
-
-       /* Program the port reset bit to start the reset process */
-       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union 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), union cvmx_usbcx_hprt, prtrst, 0);
-
-       /* Wait for the USBC_HPRT[PRTENA]. */
-       if (CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt,
-                                 prtena, ==, 1, 100000))
-               return -ETIMEDOUT;
-
-       /* 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));
-       usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GHWCFG3(usb->index));
-
-       /*
-        * 13. Program the USBC_GRXFSIZ register to select the size of the
-        *     receive FIFO (25%).
-        */
-       USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), union cvmx_usbcx_grxfsiz,
-                       rxfdep, usbcx_ghwcfg3.s.dfifodepth / 4);
-       /*
-        * 14. Program the USBC_GNPTXFSIZ register to select the size and the
-        *     start address of the non- periodic transmit FIFO for nonperiodic
-        *     transactions (50%).
-        */
-       {
-               union cvmx_usbcx_gnptxfsiz siz;
-               siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index));
-               siz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
-               siz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), siz.u32);
-       }
-       /*
-        * 15. Program the USBC_HPTXFSIZ register to select the size and start
-        *     address of the periodic transmit FIFO for periodic transactions
-        *     (25%).
-        */
-       {
-               union cvmx_usbcx_hptxfsiz siz;
-               siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index));
-               siz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
-               siz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4;
-               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index), siz.u32);
-       }
-       /* Flush all FIFOs */
-       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, txfnum, 0x10);
-       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, txfflsh, 1);
-       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl,
-                             txfflsh, ==, 0, 100);
-       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, rxfflsh, 1);
-       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl,
-                             rxfflsh, ==, 0, 100);
-
-       return 0;
-}
-
-
-/**
- * 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.
- *
- * @state: USB device state populated by
- *        cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_disable(struct cvmx_usb_state *state)
-{
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       /* Disable the port */
-       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union 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. These "changed" fields are based
- * on the last call to cvmx_usb_set_status(). In order to clear
- * them, you must update the status through cvmx_usb_set_status().
- *
- * @state: USB device state populated by
- *        cvmx_usb_initialize().
- *
- * Returns: Port status information
- */
-struct cvmx_usb_port_status cvmx_usb_get_status(struct cvmx_usb_state *state)
-{
-       union cvmx_usbcx_hprt usbc_hprt;
-       struct cvmx_usb_port_status result;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       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;
-}
-
-
-/**
- * Set the current state of the USB port. The status is used as
- * a reference for the "changed" bits returned by
- * cvmx_usb_get_status(). Other than serving as a reference, the
- * status passed to this function is not used. No fields can be
- * changed through this call.
- *
- * @state:      USB device state populated by
- *              cvmx_usb_initialize().
- * @port_status:
- *              Port status to set, most like returned by cvmx_usb_get_status()
- */
-void cvmx_usb_set_status(struct cvmx_usb_state *state, struct cvmx_usb_port_status port_status)
-{
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       usb->port_status = port_status;
-       return;
-}
-
-
-/**
- * Convert a USB transaction into a handle
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @transaction:
- *              Transaction to get handle for
- *
- * Returns: Handle
- */
-static inline int __cvmx_usb_get_submit_handle(struct cvmx_usb_internal_state *usb,
-                                              struct cvmx_usb_transaction *transaction)
-{
-       return ((unsigned long)transaction - (unsigned long)usb->transaction) /
-                       sizeof(*transaction);
-}
-
-
-/**
- * Convert a USB pipe into a handle
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe:       Pipe to get handle for
- *
- * Returns: Handle
- */
-static inline int __cvmx_usb_get_pipe_handle(struct cvmx_usb_internal_state *usb,
-                                            struct cvmx_usb_pipe *pipe)
-{
-       return ((unsigned long)pipe - (unsigned long)usb->pipe) / sizeof(*pipe);
-}
-
-
-/**
- * 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.
- *
- * @state:          USB device state populated by
- *                  cvmx_usb_initialize().
- * @flags:          Optional pipe flags defined in
- *                  enum cvmx_usb_pipe_flags.
- * @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 negative value is a pipe handle. Negative
- *         values are error codes.
- */
-int cvmx_usb_open_pipe(struct cvmx_usb_state *state, enum cvmx_usb_pipe_flags flags,
-                      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;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       if (unlikely((device_addr < 0) || (device_addr > MAX_USB_ADDRESS)))
-               return -EINVAL;
-       if (unlikely((endpoint_num < 0) || (endpoint_num > MAX_USB_ENDPOINT)))
-               return -EINVAL;
-       if (unlikely(device_speed > CVMX_USB_SPEED_LOW))
-               return -EINVAL;
-       if (unlikely((max_packet <= 0) || (max_packet > 1024)))
-               return -EINVAL;
-       if (unlikely(transfer_type > CVMX_USB_TRANSFER_INTERRUPT))
-               return -EINVAL;
-       if (unlikely((transfer_dir != CVMX_USB_DIRECTION_OUT) &&
-               (transfer_dir != CVMX_USB_DIRECTION_IN)))
-               return -EINVAL;
-       if (unlikely(interval < 0))
-               return -EINVAL;
-       if (unlikely((transfer_type == CVMX_USB_TRANSFER_CONTROL) && interval))
-               return -EINVAL;
-       if (unlikely(multi_count < 0))
-               return -EINVAL;
-       if (unlikely((device_speed != CVMX_USB_SPEED_HIGH) &&
-               (multi_count != 0)))
-               return -EINVAL;
-       if (unlikely((hub_device_addr < 0) || (hub_device_addr > MAX_USB_ADDRESS)))
-               return -EINVAL;
-       if (unlikely((hub_port < 0) || (hub_port > MAX_USB_HUB_PORT)))
-               return -EINVAL;
-
-       /* Find a free pipe */
-       pipe = usb->free_pipes.head;
-       if (!pipe)
-               return -ENOMEM;
-       __cvmx_usb_remove_pipe(&usb->free_pipes, pipe);
-       pipe->flags = flags | __CVMX_USB_PIPE_FLAGS_OPEN;
-       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;
-       /*
-        * 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;
-       __cvmx_usb_append_pipe(&usb->idle_pipes, pipe);
-
-       /*
-        * We don't need to tell the hardware about this pipe yet since
-        * it doesn't have any submitted requests
-        */
-
-       return __cvmx_usb_get_pipe_handle(usb, 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 cvmx_usb_internal_state *usb)
-{
-       union cvmx_usbcx_grxstsph rx_status;
-       int channel;
-       int bytes;
-       uint64_t address;
-       uint32_t *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_usb_read_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8);
-       ptr = cvmx_phys_to_ptr(address);
-       __cvmx_usb_write_csr64(usb, 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;
-
-       return;
-}
-
-
-/**
- * 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 cvmx_usb_internal_state *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 uint32_t *ptr = cvmx_phys_to_ptr(fifo->entry[i].address);
-               uint64_t csr_address = USB_FIFO_ADDRESS(fifo->entry[i].channel, usb->index) ^ 4;
-               int words = available;
-
-               /* Limit the amount of data to waht 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 cvmx_usb_internal_state *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), union cvmx_usbcx_gintmsk, ptxfempmsk, 1);
-               else
-                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union 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), union cvmx_usbcx_gintmsk, nptxfempmsk, 1);
-               else
-                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, nptxfempmsk, 0);
-       }
-
-       return;
-}
-
-
-/**
- * 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 cvmx_usb_internal_state *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_usb_read_csr64(usb, 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);
-
-       return;
-}
-
-/**
- * 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 cvmx_usb_internal_state *usb,
-                                            int channel,
-                                            struct cvmx_usb_pipe *pipe)
-{
-       struct cvmx_usb_transaction *transaction = pipe->head;
-       union cvmx_usb_control_header *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:
-               cvmx_dprintf("%s: ERROR - Non control stage\n", __FUNCTION__);
-               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), union 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_usb_write_csr64(usb, 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), union cvmx_usbcx_hccharx, epdir, CVMX_USB_DIRECTION_OUT);
-               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union 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->s.request_type & 0x80)
-                               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),
-                               union cvmx_usbcx_hccharx, epdir,
-                               ((header->s.request_type & 0x80) ?
-                                       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->s.request_type & 0x80))
-                       bytes_to_transfer = 0;
-               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
-                               union cvmx_usbcx_hccharx, epdir,
-                               ((header->s.request_type & 0x80) ?
-                                       CVMX_USB_DIRECTION_IN :
-                                       CVMX_USB_DIRECTION_OUT));
-               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union 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), union cvmx_usbcx_hccharx, epdir,
-                               ((header->s.request_type & 0x80) ?
-                                       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), union cvmx_usbcx_hccharx, epdir,
-                               ((header->s.request_type & 0x80) ?
-                                       CVMX_USB_DIRECTION_OUT :
-                                       CVMX_USB_DIRECTION_IN));
-               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union 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 = (bytes_to_transfer + pipe->max_packet - 1) / 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);
-       return;
-}
-
-
-/**
- * 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 cvmx_usb_internal_state *usb,
-                                    int channel,
-                                    struct cvmx_usb_pipe *pipe)
-{
-       struct cvmx_usb_transaction *transaction = pipe->head;
-
-       /* 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 locations the DMA engines use  */
-       {
-               uint64_t 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;
-               __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, dma_address);
-               __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + 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)
-                                               usbc_hcsplt.s.xactpos = 3; /* Entire payload in one go */
-                                       else
-                                               usbc_hcsplt.s.xactpos = 2; /* First part of payload */
-                               } else {
-                                       /*
-                                        * Continuing the previous data, we must
-                                        * either be in the middle or at the end
-                                        */
-                                       if (bytes_to_transfer <= 188)
-                                               usbc_hcsplt.s.xactpos = 1; /* End of payload */
-                                       else
-                                               usbc_hcsplt.s.xactpos = 0; /* Middle of payload */
-                               }
-                               /*
-                                * 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 = (bytes_to_transfer + pipe->max_packet - 1) / 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), union cvmx_usbcx_hctsizx, pid, 0);
-                               else /* Need MDATA */
-                                       USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), union 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;
-       }
-       /* Remeber 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), union cvmx_usbcx_hccharx, chena, 1);
-       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
-               __cvmx_usb_fill_tx_fifo(usb, channel);
-       return;
-}
-
-
-/**
- * Find a pipe that is ready to be scheduled to hardware.
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @list:       Pipe list to search
- * @current_frame:
- *              Frame counter to use as a time reference.
- *
- * Returns: Pipe or NULL if none are ready
- */
-static struct cvmx_usb_pipe *__cvmx_usb_find_ready_pipe(struct cvmx_usb_internal_state *usb, struct cvmx_usb_pipe_list *list, uint64_t current_frame)
-{
-       struct cvmx_usb_pipe *pipe = list->head;
-       while (pipe) {
-               if (!(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED) && pipe->head &&
-                       (pipe->next_tx_frame <= current_frame) &&
-                       ((pipe->split_sc_frame == -1) || ((((int)current_frame - (int)pipe->split_sc_frame) & 0x7f) < 0x40)) &&
-                       (!usb->active_split || (usb->active_split == pipe->head))) {
-                       CVMX_PREFETCH(pipe, 128);
-                       CVMX_PREFETCH(pipe->head, 0);
-                       return pipe;
-               }
-               pipe = pipe->next;
-       }
-       return NULL;
-}
-
-
-/**
- * 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 cvmx_usb_internal_state *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 */
-               CVMX_CLZ(channel, usb->idle_hardware_channels);
-               channel = 31 - channel;
-               if (unlikely(channel > 7))
-                       break;
-
-               /* Find a pipe needing service */
-               pipe = NULL;
-               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, usb->active_pipes + CVMX_USB_TRANSFER_ISOCHRONOUS, usb->frame_number);
-                       if (likely(!pipe))
-                               pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_INTERRUPT, usb->frame_number);
-               }
-               if (likely(!pipe)) {
-                       pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_CONTROL, usb->frame_number);
-                       if (likely(!pipe))
-                               pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_BULK, usb->frame_number);
-               }
-               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++) {
-               pipe = usb->active_pipes[ttype].head;
-               while (pipe) {
-                       if (pipe->next_tx_frame > usb->frame_number) {
-                               need_sof = 1;
-                               break;
-                       }
-                       pipe = pipe->next;
-               }
-       }
-       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, sofmsk, need_sof);
-       return;
-}
-
-
-/**
- * Call a user's callback for a specific reason.
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe:       Pipe the callback is for or NULL
- * @transaction:
- *              Transaction the callback is for or NULL
- * @reason:     Reason this callback is being called
- * @complete_code:
- *              Completion code for the transaction, if any
- */
-static void __cvmx_usb_perform_callback(struct cvmx_usb_internal_state *usb,
-                                       struct cvmx_usb_pipe *pipe,
-                                       struct cvmx_usb_transaction *transaction,
-                                       enum cvmx_usb_callback reason,
-                                       enum cvmx_usb_complete complete_code)
-{
-       cvmx_usb_callback_func_t callback = usb->callback[reason];
-       void *user_data = usb->callback_data[reason];
-       int submit_handle = -1;
-       int pipe_handle = -1;
-       int bytes_transferred = 0;
-
-       if (pipe)
-               pipe_handle = __cvmx_usb_get_pipe_handle(usb, pipe);
-
-       if (transaction) {
-               submit_handle = __cvmx_usb_get_submit_handle(usb, transaction);
-               bytes_transferred = transaction->actual_bytes;
-               /* Transactions are allowed to override the default callback */
-               if ((reason == CVMX_USB_CALLBACK_TRANSFER_COMPLETE) && transaction->callback) {
-                       callback = transaction->callback;
-                       user_data = transaction->callback_data;
-               }
-       }
-
-       if (!callback)
-               return;
-
-       callback((struct cvmx_usb_state *)usb, reason, complete_code, pipe_handle, submit_handle,
-                bytes_transferred, user_data);
-}
-
-
-/**
- * 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_perform_complete(struct cvmx_usb_internal_state *usb,
-                                       struct cvmx_usb_pipe *pipe,
-                                       struct cvmx_usb_transaction *transaction,
-                                       enum cvmx_usb_complete 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_COMPLETE_SUCCESS)) {
-                       transaction->actual_bytes = 0;     /* No bytes transferred for this packet as of yet */
-                       transaction->iso_number_packets--; /* One less ISO waiting to transfer */
-                       transaction->iso_packets++;        /* Increment to the next location in our packet array */
-                       transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
-                       goto done;
-               }
-       }
-
-       /* Remove the transaction from the pipe list */
-       if (transaction->next)
-               transaction->next->prev = transaction->prev;
-       else
-               pipe->tail = transaction->prev;
-       if (transaction->prev)
-               transaction->prev->next = transaction->next;
-       else
-               pipe->head = transaction->next;
-       if (!pipe->head) {
-               __cvmx_usb_remove_pipe(usb->active_pipes + pipe->transfer_type, pipe);
-               __cvmx_usb_append_pipe(&usb->idle_pipes, pipe);
-
-       }
-       __cvmx_usb_perform_callback(usb, pipe, transaction,
-                                   CVMX_USB_CALLBACK_TRANSFER_COMPLETE,
-                                   complete_code);
-       __cvmx_usb_free_transaction(usb, transaction);
-done:
-       return;
-}
-
-
-/**
- * Submit a usb transaction to a pipe. Called for all types
- * of transactions.
- *
- * @usb:
- * @pipe_handle:
- *                 Which pipe to submit to. Will be validated in this function.
- * @type:          Transaction type
- * @flags:         Flags for the transaction
- * @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
- * @callback:      User callback to call when the transaction completes
- * @user_data:     User's data for the callback
- *
- * Returns: Submit handle or negative on failure. Matches the result
- *         in the external API.
- */
-static int __cvmx_usb_submit_transaction(struct cvmx_usb_internal_state *usb,
-                                        int pipe_handle,
-                                        enum cvmx_usb_transfer type,
-                                        int flags,
-                                        uint64_t buffer,
-                                        int buffer_length,
-                                        uint64_t control_header,
-                                        int iso_start_frame,
-                                        int iso_number_packets,
-                                        struct cvmx_usb_iso_packet *iso_packets,
-                                        cvmx_usb_callback_func_t callback,
-                                        void *user_data)
-{
-       int submit_handle;
-       struct cvmx_usb_transaction *transaction;
-       struct cvmx_usb_pipe *pipe = usb->pipe + pipe_handle;
-
-       if (unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
-               return -EINVAL;
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-       if (unlikely(pipe->transfer_type != type))
-               return -EINVAL;
-
-       transaction = __cvmx_usb_alloc_transaction(usb);
-       if (unlikely(!transaction))
-               return -ENOMEM;
-
-       transaction->type = type;
-       transaction->flags |= flags;
-       transaction->buffer = buffer;
-       transaction->buffer_length = buffer_length;
-       transaction->control_header = control_header;
-       transaction->iso_start_frame = iso_start_frame; // FIXME: This is not used, implement it
-       transaction->iso_number_packets = iso_number_packets;
-       transaction->iso_packets = iso_packets;
-       transaction->callback = callback;
-       transaction->callback_data = user_data;
-       if (transaction->type == CVMX_USB_TRANSFER_CONTROL)
-               transaction->stage = CVMX_USB_STAGE_SETUP;
-       else
-               transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
-
-       transaction->next = NULL;
-       if (pipe->tail) {
-               transaction->prev = pipe->tail;
-               transaction->prev->next = transaction;
-       } else {
-               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;
-               transaction->prev = NULL;
-               pipe->head = transaction;
-               __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe);
-               __cvmx_usb_append_pipe(usb->active_pipes + pipe->transfer_type, pipe);
-       }
-       pipe->tail = transaction;
-
-       submit_handle = __cvmx_usb_get_submit_handle(usb, transaction);
-
-       /* We may need to schedule the pipe if this was the head of the pipe */
-       if (!transaction->prev)
-               __cvmx_usb_schedule(usb, 0);
-
-       return submit_handle;
-}
-
-
-/**
- * Call to submit a USB Bulk transfer to a pipe.
- *
- * @state:         USB device state populated by
- *                 cvmx_usb_initialize().
- * @pipe_handle:
- *                 Handle to the pipe for the transfer.
- * @buffer:        Physical address of the data buffer in
- *                 memory. Note that this is NOT A POINTER, but
- *                 the full 64bit physical address of the
- *                 buffer. This may be zero if buffer_length is
- *                 zero.
- * @buffer_length:
- *                 Length of buffer in bytes.
- * @callback:      Function to call when this transaction
- *                 completes. If the return value of this
- *                 function isn't an error, then this function
- *                 is guaranteed to be called when the
- *                 transaction completes. If this parameter is
- *                 NULL, then the generic callback registered
- *                 through cvmx_usb_register_callback is
- *                 called. If both are NULL, then there is no
- *                 way to know when a transaction completes.
- * @user_data:     User supplied data returned when the
- *                 callback is called. This is only used if
- *                 callback in not NULL.
- *
- * Returns: A submitted transaction handle or negative on
- *         failure. Negative values are error codes.
- */
-int cvmx_usb_submit_bulk(struct cvmx_usb_state *state, int pipe_handle,
-                        uint64_t buffer, int buffer_length,
-                        cvmx_usb_callback_func_t callback,
-                        void *user_data)
-{
-       int submit_handle;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       /* Pipe handle checking is done later in a common place */
-       if (unlikely(!buffer))
-               return -EINVAL;
-       if (unlikely(buffer_length < 0))
-               return -EINVAL;
-
-       submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
-                                                     CVMX_USB_TRANSFER_BULK,
-                                                     0, /* flags */
-                                                     buffer,
-                                                     buffer_length,
-                                                     0, /* control_header */
-                                                     0, /* iso_start_frame */
-                                                     0, /* iso_number_packets */
-                                                     NULL, /* iso_packets */
-                                                     callback,
-                                                     user_data);
-       return submit_handle;
-}
-
-
-/**
- * Call to submit a USB Interrupt transfer to a pipe.
- *
- * @state:         USB device state populated by
- *                 cvmx_usb_initialize().
- * @pipe_handle:
- *                 Handle to the pipe for the transfer.
- * @buffer:        Physical address of the data buffer in
- *                 memory. Note that this is NOT A POINTER, but
- *                 the full 64bit physical address of the
- *                 buffer. This may be zero if buffer_length is
- *                 zero.
- * @buffer_length:
- *                 Length of buffer in bytes.
- * @callback:      Function to call when this transaction
- *                 completes. If the return value of this
- *                 function isn't an error, then this function
- *                 is guaranteed to be called when the
- *                 transaction completes. If this parameter is
- *                 NULL, then the generic callback registered
- *                 through cvmx_usb_register_callback is
- *                 called. If both are NULL, then there is no
- *                 way to know when a transaction completes.
- * @user_data:     User supplied data returned when the
- *                 callback is called. This is only used if
- *                 callback in not NULL.
- *
- * Returns: A submitted transaction handle or negative on
- *         failure. Negative values are error codes.
- */
-int cvmx_usb_submit_interrupt(struct cvmx_usb_state *state, int pipe_handle,
-                             uint64_t buffer, int buffer_length,
-                             cvmx_usb_callback_func_t callback,
-                             void *user_data)
-{
-       int submit_handle;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       /* Pipe handle checking is done later in a common place */
-       if (unlikely(!buffer))
-               return -EINVAL;
-       if (unlikely(buffer_length < 0))
-               return -EINVAL;
-
-       submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
-                                                     CVMX_USB_TRANSFER_INTERRUPT,
-                                                     0, /* flags */
-                                                     buffer,
-                                                     buffer_length,
-                                                     0, /* control_header */
-                                                     0, /* iso_start_frame */
-                                                     0, /* iso_number_packets */
-                                                     NULL, /* iso_packets */
-                                                     callback,
-                                                     user_data);
-       return submit_handle;
-}
-
-
-/**
- * Call to submit a USB Control transfer to a pipe.
- *
- * @state:         USB device state populated by
- *                 cvmx_usb_initialize().
- * @pipe_handle:
- *                 Handle to the pipe for the transfer.
- * @control_header:
- *                 USB 8 byte control header physical address.
- *                 Note that this is NOT A POINTER, but the
- *                 full 64bit physical address of the buffer.
- * @buffer:        Physical address of the data buffer in
- *                 memory. Note that this is NOT A POINTER, but
- *                 the full 64bit physical address of the
- *                 buffer. This may be zero if buffer_length is
- *                 zero.
- * @buffer_length:
- *                 Length of buffer in bytes.
- * @callback:      Function to call when this transaction
- *                 completes. If the return value of this
- *                 function isn't an error, then this function
- *                 is guaranteed to be called when the
- *                 transaction completes. If this parameter is
- *                 NULL, then the generic callback registered
- *                 through cvmx_usb_register_callback is
- *                 called. If both are NULL, then there is no
- *                 way to know when a transaction completes.
- * @user_data:     User supplied data returned when the
- *                 callback is called. This is only used if
- *                 callback in not NULL.
- *
- * Returns: A submitted transaction handle or negative on
- *         failure. Negative values are error codes.
- */
-int cvmx_usb_submit_control(struct cvmx_usb_state *state, int pipe_handle,
-                           uint64_t control_header,
-                           uint64_t buffer, int buffer_length,
-                           cvmx_usb_callback_func_t callback,
-                           void *user_data)
-{
-       int submit_handle;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       union cvmx_usb_control_header *header =
-               cvmx_phys_to_ptr(control_header);
-
-       /* Pipe handle checking is done later in a common place */
-       if (unlikely(!control_header))
-               return -EINVAL;
-       /* Some drivers send a buffer with a zero length. God only knows why */
-       if (unlikely(buffer && (buffer_length < 0)))
-               return -EINVAL;
-       if (unlikely(!buffer && (buffer_length != 0)))
-               return -EINVAL;
-       if ((header->s.request_type & 0x80) == 0)
-               buffer_length = le16_to_cpu(header->s.length);
-
-       submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
-                                                     CVMX_USB_TRANSFER_CONTROL,
-                                                     0, /* flags */
-                                                     buffer,
-                                                     buffer_length,
-                                                     control_header,
-                                                     0, /* iso_start_frame */
-                                                     0, /* iso_number_packets */
-                                                     NULL, /* iso_packets */
-                                                     callback,
-                                                     user_data);
-       return submit_handle;
-}
-
-
-/**
- * Call to submit a USB Isochronous transfer to a pipe.
- *
- * @state:         USB device state populated by
- *                 cvmx_usb_initialize().
- * @pipe_handle:
- *                 Handle to the pipe for the transfer.
- * @start_frame:
- *                 Number of frames into the future to schedule
- *                 this transaction.
- * @flags:         Flags to control the transfer. See
- *                 enum cvmx_usb_isochronous_flags for the flag
- *                 definitions.
- * @number_packets:
- *                 Number of sequential packets to transfer.
- *                 "packets" is a pointer to an array of this
- *                 many packet structures.
- * @packets:       Description of each transfer packet as
- *                 defined by struct cvmx_usb_iso_packet. The array
- *                 pointed to here must stay valid until the
- *                 complete callback is called.
- * @buffer:        Physical address of the data buffer in
- *                 memory. Note that this is NOT A POINTER, but
- *                 the full 64bit physical address of the
- *                 buffer. This may be zero if buffer_length is
- *                 zero.
- * @buffer_length:
- *                 Length of buffer in bytes.
- * @callback:      Function to call when this transaction
- *                 completes. If the return value of this
- *                 function isn't an error, then this function
- *                 is guaranteed to be called when the
- *                 transaction completes. If this parameter is
- *                 NULL, then the generic callback registered
- *                 through cvmx_usb_register_callback is
- *                 called. If both are NULL, then there is no
- *                 way to know when a transaction completes.
- * @user_data:     User supplied data returned when the
- *                 callback is called. This is only used if
- *                 callback in not NULL.
- *
- * Returns: A submitted transaction handle or negative on
- *         failure. Negative values are error codes.
- */
-int cvmx_usb_submit_isochronous(struct cvmx_usb_state *state, int pipe_handle,
-                               int start_frame, int flags,
-                               int number_packets,
-                               struct cvmx_usb_iso_packet packets[],
-                               uint64_t buffer, int buffer_length,
-                               cvmx_usb_callback_func_t callback,
-                               void *user_data)
-{
-       int submit_handle;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       /* Pipe handle checking is done later in a common place */
-       if (unlikely(start_frame < 0))
-               return -EINVAL;
-       if (unlikely(flags & ~(CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT | CVMX_USB_ISOCHRONOUS_FLAGS_ASAP)))
-               return -EINVAL;
-       if (unlikely(number_packets < 1))
-               return -EINVAL;
-       if (unlikely(!packets))
-               return -EINVAL;
-       if (unlikely(!buffer))
-               return -EINVAL;
-       if (unlikely(buffer_length < 0))
-               return -EINVAL;
-
-       submit_handle = __cvmx_usb_submit_transaction(usb, pipe_handle,
-                                                     CVMX_USB_TRANSFER_ISOCHRONOUS,
-                                                     flags,
-                                                     buffer,
-                                                     buffer_length,
-                                                     0, /* control_header */
-                                                     start_frame,
-                                                     number_packets,
-                                                     packets,
-                                                     callback,
-                                                     user_data);
-       return submit_handle;
-}
-
-
-/**
- * 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.
- *
- * @state:      USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe_handle:
- *              Pipe handle to cancel requests in.
- * @submit_handle:
- *              Handle to transaction to cancel, returned by the submit function.
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_cancel(struct cvmx_usb_state *state, int pipe_handle, int submit_handle)
-{
-       struct cvmx_usb_transaction *transaction;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       struct cvmx_usb_pipe *pipe = usb->pipe + pipe_handle;
-
-       if (unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
-               return -EINVAL;
-       if (unlikely((submit_handle < 0) || (submit_handle >= MAX_TRANSACTIONS)))
-               return -EINVAL;
-
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-
-       transaction = usb->transaction + submit_handle;
-
-       /* Fail if this transaction already completed */
-       if (unlikely((transaction->flags & __CVMX_USB_TRANSACTION_FLAGS_IN_USE) == 0))
-               return -EINVAL;
-
-       /*
-        * If the transaction is the HEAD of the queue and scheduled. We need to
-        * treat it special
-        */
-       if ((pipe->head == 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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_CANCEL);
-       return 0;
-}
-
-
-/**
- * Cancel all outstanding requests in a pipe. Logically all this
- * does is call cvmx_usb_cancel() in a loop.
- *
- * @state:      USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe_handle:
- *              Pipe handle to cancel requests in.
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_cancel_all(struct cvmx_usb_state *state, int pipe_handle)
-{
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       struct cvmx_usb_pipe *pipe = usb->pipe + pipe_handle;
-
-       if (unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
-               return -EINVAL;
-
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-
-       /* Simply loop through and attempt to cancel each transaction */
-       while (pipe->head) {
-               int result = cvmx_usb_cancel(state, pipe_handle,
-                       __cvmx_usb_get_submit_handle(usb, pipe->head));
-               if (unlikely(result != 0))
-                       return result;
-       }
-       return 0;
-}
-
-
-/**
- * Close a pipe created with cvmx_usb_open_pipe().
- *
- * @state:      USB device state populated by
- *              cvmx_usb_initialize().
- * @pipe_handle:
- *              Pipe handle to close.
- *
- * Returns: 0 or a negative error code. EBUSY is returned if the pipe has
- *         outstanding transfers.
- */
-int cvmx_usb_close_pipe(struct cvmx_usb_state *state, int pipe_handle)
-{
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       struct cvmx_usb_pipe *pipe = usb->pipe + pipe_handle;
-
-       if (unlikely((pipe_handle < 0) || (pipe_handle >= MAX_PIPES)))
-               return -EINVAL;
-
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-
-       /* Fail if the pipe has pending transactions */
-       if (unlikely(pipe->head))
-               return -EBUSY;
-
-       pipe->flags = 0;
-       __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe);
-       __cvmx_usb_append_pipe(&usb->free_pipes, pipe);
-
-       return 0;
-}
-
-
-/**
- * Register a function to be called when various USB events occur.
- *
- * @state:     USB device state populated by
- *            cvmx_usb_initialize().
- * @reason:    Which event to register for.
- * @callback:  Function to call when the event occurs.
- * @user_data: User data parameter to the function.
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_register_callback(struct cvmx_usb_state *state,
-                              enum cvmx_usb_callback reason,
-                              cvmx_usb_callback_func_t callback,
-                              void *user_data)
-{
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       if (unlikely(reason >= __CVMX_USB_CALLBACK_END))
-               return -EINVAL;
-       if (unlikely(!callback))
-               return -EINVAL;
-
-       usb->callback[reason] = callback;
-       usb->callback_data[reason] = user_data;
-
-       return 0;
-}
-
-
-/**
- * Get the current USB protocol level frame number. The frame
- * number is always in the range of 0-0x7ff.
- *
- * @state: USB device state populated by
- *        cvmx_usb_initialize().
- *
- * Returns: USB frame number
- */
-int cvmx_usb_get_frame_number(struct cvmx_usb_state *state)
-{
-       int frame_number;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-       union cvmx_usbcx_hfnum usbc_hfnum;
-
-       usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
-       frame_number = usbc_hfnum.s.frnum;
-
-       return frame_number;
-}
-
-
-/**
- * Poll a channel for status
- *
- * @usb:     USB device
- * @channel: Channel to poll
- *
- * Returns: Zero on success
- */
-static int __cvmx_usb_poll_channel(struct cvmx_usb_internal_state *usb, int channel)
-{
-       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 {
-                               cvmx_dprintf("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];
-       CVMX_PREFETCH(pipe, 0);
-       CVMX_PREFETCH(pipe, 128);
-       if (!pipe)
-               return 0;
-       transaction = pipe->head;
-       CVMX_PREFETCH0(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
-        * transfered
-        */
-       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 (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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_STALL);
-       } else if (usbc_hcint.s.xacterr) {
-               /*
-                * We know at least one packet worked if we get a ACK or NAK.
-                * Reset the retry counter
-                */
-               if (usbc_hcint.s.nak || usbc_hcint.s.ack)
-                       transaction->retries = 0;
-               transaction->retries++;
-               if (transaction->retries > MAX_RETRIES) {
-                       /*
-                        * XactErr as a response means the device signaled
-                        * something wrong with the transfer. For example, PID
-                        * toggle errors cause these
-                        */
-                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_XACTERR);
-               } else {
-                       /*
-                        * If this was a split then clear our split in progress
-                        * marker
-                        */
-                       if (usb->active_split == transaction)
-                               usb->active_split = NULL;
-                       /*
-                        * Rewind to the beginning of the transaction by anding
-                        * off the split complete bit
-                        */
-                       transaction->stage &= ~1;
-                       pipe->split_sc_frame = -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 if (usbc_hcint.s.bblerr) {
-               /* Babble Error (BblErr) */
-               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_BABBLEERR);
-       } else if (usbc_hcint.s.datatglerr) {
-               /* We'll retry the exact same transaction again */
-               transaction->retries++;
-       } 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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-               } 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:
-                       switch (transaction->stage) {
-                       case CVMX_USB_STAGE_NON_CONTROL:
-                       case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
-                               /* This should be impossible */
-                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_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 {
-                                       union cvmx_usb_control_header *header =
-                                               cvmx_phys_to_ptr(transaction->control_header);
-                                       if (header->s.length)
-                                               transaction->stage = CVMX_USB_STAGE_DATA;
-                                       else
-                                               transaction->stage = CVMX_USB_STAGE_STATUS;
-                               }
-                               break;
-                       case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
-                               {
-                                       union cvmx_usb_control_header *header =
-                                               cvmx_phys_to_ptr(transaction->control_header);
-                                       if (header->s.length)
-                                               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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                               break;
-                       case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
-                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                               break;
-                       }
-                       break;
-               case CVMX_USB_TRANSFER_BULK:
-               case CVMX_USB_TRANSFER_INTERRUPT:
-                       /*
-                        * 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 {
-                                               if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
-                                                       pipe->next_tx_frame += pipe->interval;
-                                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                                       }
-                               }
-                       } else {
-                               if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
-                                   (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
-                                   (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)) {
-                                       if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
-                                               pipe->next_tx_frame += pipe->interval;
-                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                               }
-                       }
-                       break;
-               case CVMX_USB_TRANSFER_ISOCHRONOUS:
-                       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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                                       }
-                               } else {
-                                       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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                                               }
-                                       } else
-                                               transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
-                               }
-                       } else {
-                               pipe->next_tx_frame += pipe->interval;
-                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
-                       }
-                       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((struct cvmx_usb_state *)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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
-               }
-       }
-       return 0;
-}
-
-
-/**
- * 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.
- *
- * @state:     USB device state populated by
- *             cvmx_usb_initialize().
- *
- * Returns: 0 or a negative error code.
- */
-int cvmx_usb_poll(struct cvmx_usb_state *state)
-{
-       union cvmx_usbcx_hfnum usbc_hfnum;
-       union cvmx_usbcx_gintsts usbc_gintsts;
-       struct cvmx_usb_internal_state *usb = (struct cvmx_usb_internal_state *)state;
-
-       CVMX_PREFETCH(usb, 0);
-       CVMX_PREFETCH(usb, 1*128);
-       CVMX_PREFETCH(usb, 2*128);
-       CVMX_PREFETCH(usb, 3*128);
-       CVMX_PREFETCH(usb, 4*128);
-
-       /* 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
-                */
-               __cvmx_usb_perform_callback(usb, NULL, NULL,
-                                           CVMX_USB_CALLBACK_PORT_CHANGED,
-                                           CVMX_USB_COMPLETE_SUCCESS);
-               /* 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;
-                       CVMX_CLZ(channel, usbc_haint.u32);
-                       channel = 31 - channel;
-                       __cvmx_usb_poll_channel(usb, channel);
-                       usbc_haint.u32 ^= 1<<channel;
-               }
-       }
-
-       __cvmx_usb_schedule(usb, usbc_gintsts.s.sof);
-
-       return 0;
-}
diff --git a/drivers/staging/octeon-usb/cvmx-usb.h b/drivers/staging/octeon-usb/cvmx-usb.h
deleted file mode 100644 (file)
index 8bf3696..0000000
+++ /dev/null
@@ -1,542 +0,0 @@
-/***********************license start***************
- * 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.
- ***********************license end**************************************/
-
-
-/**
- * "cvmx-usb.h" defines a set of low level USB functions to help
- * developers create Octeon USB drivers for various operating
- * systems. These functions provide a generic API to the Octeon
- * USB blocks, hiding the internal hardware specific
- * operations.
- *
- * At a high level the device driver needs to:
- *
- * - Call cvmx_usb_get_num_ports() to get the number of
- *   supported ports.
- * - Call cvmx_usb_initialize() for each Octeon USB port.
- * - Enable the port using cvmx_usb_enable().
- * - Either periodically, or in an interrupt handler, call
- *   cvmx_usb_poll() to service USB events.
- * - Manage pipes using cvmx_usb_open_pipe() and
- *   cvmx_usb_close_pipe().
- * - Manage transfers using cvmx_usb_submit_*() and
- *   cvmx_usb_cancel*().
- * - Shutdown USB on unload using cvmx_usb_shutdown().
- *
- * To monitor USB status changes, the device driver must use
- * cvmx_usb_register_callback() to register for events that it
- * is interested in. Below are a few hints on successfully
- * implementing a driver on top of this API.
- *
- * == Initialization ==
- *
- * When a driver is first loaded, it is normally not necessary
- * to bring up the USB port completely. Most operating systems
- * expect to initialize and enable the port in two independent
- * steps. Normally an operating system will probe hardware,
- * initialize anything found, and then enable the hardware.
- *
- * In the probe phase you should:
- * - Use cvmx_usb_get_num_ports() to determine the number of
- *   USB port to be supported.
- * - Allocate space for a struct cvmx_usb_state for each
- *   port.
- * - Tell the operating system about each port
- *
- * In the initialization phase you should:
- * - Use cvmx_usb_initialize() on each port.
- * - Do not call cvmx_usb_enable(). This leaves the USB port in
- *   the disabled state until the operating system is ready.
- *
- * Finally, in the enable phase you should:
- * - Call cvmx_usb_enable() on the appropriate port.
- * - Note that some operating system use a RESET instead of an
- *   enable call. To implement RESET, you should call
- *   cvmx_usb_disable() followed by cvmx_usb_enable().
- *
- * == Locking ==
- *
- * All of the functions in the cvmx-usb API assume exclusive
- * access to the USB hardware and internal data structures. This
- * means that the driver must provide locking as necessary.
- *
- * In the single CPU state it is normally enough to disable
- * interrupts before every call to cvmx_usb*() and enable them
- * again after the call is complete. Keep in mind that it is
- * very common for the callback handlers to make additional
- * calls into cvmx-usb, so the disable/enable must be protected
- * against recursion. As an example, the Linux kernel
- * local_irq_save() and local_irq_restore() are perfect for this
- * in the non SMP case.
- *
- * In the SMP case, locking is more complicated. For SMP you not
- * only need to disable interrupts on the local core, but also
- * take a lock to make sure that another core cannot call
- * cvmx-usb.
- *
- * == Port callback ==
- *
- * The port callback prototype needs to look as follows:
- *
- * void port_callback(struct cvmx_usb_state *usb,
- *                    enum cvmx_usb_callback reason,
- *                    enum cvmx_usb_complete status,
- *                    int pipe_handle,
- *                    int submit_handle,
- *                    int bytes_transferred,
- *                    void *user_data);
- * - "usb" is the struct cvmx_usb_state for the port.
- * - "reason" will always be CVMX_USB_CALLBACK_PORT_CHANGED.
- * - "status" will always be CVMX_USB_COMPLETE_SUCCESS.
- * - "pipe_handle" will always be -1.
- * - "submit_handle" will always be -1.
- * - "bytes_transferred" will always be 0.
- * - "user_data" is the void pointer originally passed along
- *   with the callback. Use this for any state information you
- *   need.
- *
- * The port callback will be called whenever the user plugs /
- * unplugs a device from the port. It will not be called when a
- * device is plugged / unplugged from a hub connected to the
- * root port. Normally all the callback needs to do is tell the
- * operating system to poll the root hub for status. Under
- * Linux, this is performed by calling usb_hcd_poll_rh_status().
- * In the Linux driver we use "user_data". to pass around the
- * Linux "hcd" structure. Once the port callback completes,
- * Linux automatically calls octeon_usb_hub_status_data() which
- * uses cvmx_usb_get_status() to determine the root port status.
- *
- * == Complete callback ==
- *
- * The completion callback prototype needs to look as follows:
- *
- * void complete_callback(struct cvmx_usb_state *usb,
- *                        enum cvmx_usb_callback reason,
- *                        enum cvmx_usb_complete status,
- *                        int pipe_handle,
- *                        int submit_handle,
- *                        int bytes_transferred,
- *                        void *user_data);
- * - "usb" is the struct cvmx_usb_state for the port.
- * - "reason" will always be CVMX_USB_CALLBACK_TRANSFER_COMPLETE.
- * - "status" will be one of the cvmx_usb_complete enumerations.
- * - "pipe_handle" is the handle to the pipe the transaction
- *   was originally submitted on.
- * - "submit_handle" is the handle returned by the original
- *   cvmx_usb_submit_* call.
- * - "bytes_transferred" is the number of bytes successfully
- *   transferred in the transaction. This will be zero on most
- *   error conditions.
- * - "user_data" is the void pointer originally passed along
- *   with the callback. Use this for any state information you
- *   need. For example, the Linux "urb" is stored in here in the
- *   Linux driver.
- *
- * In general your callback handler should use "status" and
- * "bytes_transferred" to tell the operating system the how the
- * transaction completed. Normally the pipe is not changed in
- * this callback.
- *
- * == Canceling transactions ==
- *
- * When a transaction is cancelled using cvmx_usb_cancel*(), the
- * actual length of time until the complete callback is called
- * can vary greatly. It may be called before cvmx_usb_cancel*()
- * returns, or it may be called a number of usb frames in the
- * future once the hardware frees the transaction. In either of
- * these cases, the complete handler will receive
- * CVMX_USB_COMPLETE_CANCEL.
- *
- * == Handling pipes ==
- *
- * USB "pipes" is a software construct created by this API to
- * enable the ordering of usb transactions to a device endpoint.
- * Octeon's underlying hardware doesn't have any concept
- * equivalent to "pipes". The hardware instead has eight
- * channels that can be used simultaneously to have up to eight
- * transaction in process at the same time. In order to maintain
- * ordering in a pipe, the transactions for a pipe will only be
- * active in one hardware channel at a time. From an API user's
- * perspective, this doesn't matter but it can be helpful to
- * keep this in mind when you are probing hardware while
- * debugging.
- *
- * Also keep in mind that usb transactions contain state
- * information about the previous transaction to the same
- * endpoint. Each transaction has a PID toggle that changes 0/1
- * between each sub packet. This is maintained in the pipe data
- * structures. For this reason, you generally cannot create and
- * destroy a pipe for every transaction. A sequence of
- * transaction to the same endpoint must use the same pipe.
- *
- * == Root Hub ==
- *
- * Some operating systems view the usb root port as a normal usb
- * hub. These systems attempt to control the root hub with
- * messages similar to the usb 2.0 spec for hub control and
- * status. For these systems it may be necessary to write
- * function to decode standard usb control messages into
- * equivalent cvmx-usb API calls.
- *
- * == Interrupts ==
- *
- * If you plan on using usb interrupts, cvmx_usb_poll() must be
- * called on every usb interrupt. It will read the usb state,
- * call any needed callbacks, and schedule transactions as
- * needed. Your device driver needs only to hookup an interrupt
- * handler and call cvmx_usb_poll(). Octeon's usb port 0 causes
- * CIU bit CIU_INT*_SUM0[USB] to be set (bit 56). For port 1,
- * CIU bit CIU_INT_SUM1[USB1] is set (bit 17). How these bits
- * are turned into interrupt numbers is operating system
- * specific. For Linux, there are the convenient defines
- * OCTEON_IRQ_USB0 and OCTEON_IRQ_USB1 for the IRQ numbers.
- *
- * If you aren't using interrupts, simple call cvmx_usb_poll()
- * in your main processing loop.
- */
-
-#ifndef __CVMX_USB_H__
-#define __CVMX_USB_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_complete - possible callback function status codes
- *
- * @CVMX_USB_COMPLETE_SUCCESS:   The transaction / operation finished without
- *                               any errors
- * @CVMX_USB_COMPLETE_SHORT:     FIXME: This is currently not implemented
- * @CVMX_USB_COMPLETE_CANCEL:    The transaction was canceled while in flight by
- *                               a user call to cvmx_usb_cancel
- * @CVMX_USB_COMPLETE_ERROR:     The transaction aborted with an unexpected
- *                               error status
- * @CVMX_USB_COMPLETE_STALL:     The transaction received a USB STALL response
- *                               from the device
- * @CVMX_USB_COMPLETE_XACTERR:   The transaction failed with an error from the
- *                               device even after a number of retries
- * @CVMX_USB_COMPLETE_DATATGLERR: The transaction failed with a data toggle
- *                               error even after a number of retries
- * @CVMX_USB_COMPLETE_BABBLEERR:  The transaction failed with a babble error
- * @CVMX_USB_COMPLETE_FRAMEERR:          The transaction failed with a frame error
- *                               even after a number of retries
- */
-enum cvmx_usb_complete {
-       CVMX_USB_COMPLETE_SUCCESS,
-       CVMX_USB_COMPLETE_SHORT,
-       CVMX_USB_COMPLETE_CANCEL,
-       CVMX_USB_COMPLETE_ERROR,
-       CVMX_USB_COMPLETE_STALL,
-       CVMX_USB_COMPLETE_XACTERR,
-       CVMX_USB_COMPLETE_DATATGLERR,
-       CVMX_USB_COMPLETE_BABBLEERR,
-       CVMX_USB_COMPLETE_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 {
-       uint32_t reserved               : 25;
-       uint32_t port_enabled           : 1;
-       uint32_t port_over_current      : 1;
-       uint32_t port_powered           : 1;
-       enum cvmx_usb_speed port_speed  : 2;
-       uint32_t connected              : 1;
-       uint32_t connect_change         : 1;
-};
-
-/**
- * union cvmx_usb_control_header - the structure of a Control packet header
- *
- * @s.request_type:    Bit 7 tells the direction: 1=IN, 0=OUT
- * @s.request          The standard usb request to make
- * @s.value            Value parameter for the request in little endian format
- * @s.index            Index for the request in little endian format
- * @s.length           Length of the data associated with this request in
- *                     little endian format
- */
-union cvmx_usb_control_header {
-       uint64_t u64;
-       struct {
-               uint64_t request_type   : 8;
-               uint64_t request        : 8;
-               uint64_t value          : 16;
-               uint64_t index          : 16;
-               uint64_t length         : 16;
-       } s;
-};
-
-/**
- * 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_complete status;
-};
-
-/**
- * enum cvmx_usb_callback - possible callback reasons for the USB API
- *
- * @CVMX_USB_CALLBACK_TRANSFER_COMPLETE: A callback of this type is called when
- *                                      a submitted transfer completes. The
- *                                      completion callback will be called even
- *                                      if the transfer fails or is canceled.
- *                                      The status parameter will contain
- *                                      details of why he callback was called.
- * @CVMX_USB_CALLBACK_PORT_CHANGED:     The status of the port changed. For
- *                                      example, someone may have plugged a
- *                                      device in. The status parameter
- *                                      contains CVMX_USB_COMPLETE_SUCCESS. Use
- *                                      cvmx_usb_get_status() to get the new
- *                                      port status.
- * @__CVMX_USB_CALLBACK_END:            Do not use. Used internally for array
- *                                      bounds.
- */
-enum cvmx_usb_callback {
-       CVMX_USB_CALLBACK_TRANSFER_COMPLETE,
-       CVMX_USB_CALLBACK_PORT_CHANGED,
-       __CVMX_USB_CALLBACK_END
-};
-
-/**
- * USB state internal data. The contents of this structure
- * may change in future SDKs. No data in it should be referenced
- * by user's of this API.
- */
-struct cvmx_usb_state {
-       char data[65536];
-};
-
-/**
- * USB callback functions are always of the following type.
- * The parameters are as follows:
- *      - state = USB device state populated by
- *        cvmx_usb_initialize().
- *      - reason = The enum cvmx_usb_callback used to register
- *        the callback.
- *      - status = The enum cvmx_usb_complete representing the
- *        status code of a transaction.
- *      - pipe_handle = The Pipe that caused this callback, or
- *        -1 if this callback wasn't associated with a pipe.
- *      - submit_handle = Transfer submit handle causing this
- *        callback, or -1 if this callback wasn't associated
- *        with a transfer.
- *      - Actual number of bytes transfer.
- *      - user_data = The user pointer supplied to the
- *        function cvmx_usb_submit() or
- *        cvmx_usb_register_callback() */
-typedef void (*cvmx_usb_callback_func_t)(struct cvmx_usb_state *state,
-                                         enum cvmx_usb_callback reason,
-                                         enum cvmx_usb_complete status,
-                                         int pipe_handle, int submit_handle,
-                                         int bytes_transferred, void *user_data);
-
-/**
- * enum cvmx_usb_initialize_flags - flags to pass 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_AUTO:     Automatically determine clock type
- *                                           based on function in
- *                                           cvmx-helper-board.c.
- * @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_AUTO            = 0,
-       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 - flags for passing when a pipe is created.
- *                           Currently no flags need to be passed.
- *
- * @__CVMX_USB_PIPE_FLAGS_OPEN:             Used internally to determine if a pipe is
- *                                  open. Do not use.
- * @__CVMX_USB_PIPE_FLAGS_SCHEDULED: Used internally to determine if a pipe is
- *                                  actively using hardware. Do not use.
- * @__CVMX_USB_PIPE_FLAGS_NEED_PING: Used internally to determine if a high
- *                                  speed pipe is in the ping state. Do not
- *                                  use.
- */
-enum cvmx_usb_pipe_flags {
-       __CVMX_USB_PIPE_FLAGS_OPEN      = 1 << 16,
-       __CVMX_USB_PIPE_FLAGS_SCHEDULED = 1 << 17,
-       __CVMX_USB_PIPE_FLAGS_NEED_PING = 1 << 18,
-};
-
-extern int cvmx_usb_get_num_ports(void);
-extern int cvmx_usb_initialize(struct cvmx_usb_state *state, int usb_port_number,
-                              enum cvmx_usb_initialize_flags flags);
-extern int cvmx_usb_shutdown(struct cvmx_usb_state *state);
-extern int cvmx_usb_enable(struct cvmx_usb_state *state);
-extern int cvmx_usb_disable(struct cvmx_usb_state *state);
-extern struct cvmx_usb_port_status cvmx_usb_get_status(struct cvmx_usb_state *state);
-extern void cvmx_usb_set_status(struct cvmx_usb_state *state, struct cvmx_usb_port_status port_status);
-extern int cvmx_usb_open_pipe(struct cvmx_usb_state *state,
-                              enum cvmx_usb_pipe_flags flags,
-                              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);
-extern int cvmx_usb_submit_bulk(struct cvmx_usb_state *state, int pipe_handle,
-                                uint64_t buffer, int buffer_length,
-                                cvmx_usb_callback_func_t callback,
-                                void *user_data);
-extern int cvmx_usb_submit_interrupt(struct cvmx_usb_state *state, int pipe_handle,
-                                     uint64_t buffer, int buffer_length,
-                                     cvmx_usb_callback_func_t callback,
-                                     void *user_data);
-extern int cvmx_usb_submit_control(struct cvmx_usb_state *state, int pipe_handle,
-                                   uint64_t control_header,
-                                   uint64_t buffer, int buffer_length,
-                                   cvmx_usb_callback_func_t callback,
-                                   void *user_data);
-
-/**
- * enum cvmx_usb_isochronous_flags - flags to pass the
- *                                  cvmx_usb_submit_isochronous() function.
- *
- * @CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT: Do not return an error if a transfer
- *                                         is less than the maximum packet size
- *                                         of the device.
- * @CVMX_USB_ISOCHRONOUS_FLAGS_ASAP:       Schedule the transaction as soon as
- *                                         possible.
- */
-enum cvmx_usb_isochronous_flags {
-       CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT  = 1 << 0,
-       CVMX_USB_ISOCHRONOUS_FLAGS_ASAP         = 1 << 1,
-};
-
-extern int cvmx_usb_submit_isochronous(struct cvmx_usb_state *state, int pipe_handle,
-                                       int start_frame, int flags,
-                                       int number_packets,
-                                       struct cvmx_usb_iso_packet packets[],
-                                       uint64_t buffer, int buffer_length,
-                                       cvmx_usb_callback_func_t callback,
-                                       void *user_data);
-extern int cvmx_usb_cancel(struct cvmx_usb_state *state, int pipe_handle,
-                          int submit_handle);
-extern int cvmx_usb_cancel_all(struct cvmx_usb_state *state, int pipe_handle);
-extern int cvmx_usb_close_pipe(struct cvmx_usb_state *state, int pipe_handle);
-extern int cvmx_usb_register_callback(struct cvmx_usb_state *state,
-                                     enum cvmx_usb_callback reason,
-                                     cvmx_usb_callback_func_t callback,
-                                     void *user_data);
-extern int cvmx_usb_get_frame_number(struct cvmx_usb_state *state);
-extern int cvmx_usb_poll(struct cvmx_usb_state *state);
-
-#endif  /* __CVMX_USB_H__ */
diff --git a/drivers/staging/octeon-usb/cvmx-usbnx-defs.h b/drivers/staging/octeon-usb/cvmx-usbnx-defs.h
deleted file mode 100644 (file)
index e06aafa..0000000
+++ /dev/null
@@ -1,885 +0,0 @@
-/***********************license start***************
- * 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.
- ***********************license end**************************************/
-
-
-/**
- * cvmx-usbnx-defs.h
- *
- * Configuration and status register (CSR) type definitions for
- * Octeon usbnx.
- *
- */
-#ifndef __CVMX_USBNX_TYPEDEFS_H__
-#define __CVMX_USBNX_TYPEDEFS_H__
-
-#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_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 {
-       uint64_t 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_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 {
-               uint64_t reserved_20_63 : 44;
-               uint64_t divide2        : 2;
-               uint64_t hclk_rst       : 1;
-               uint64_t p_x_on         : 1;
-               uint64_t reserved_14_15 : 2;
-               uint64_t p_com_on       : 1;
-               uint64_t p_c_sel        : 2;
-               uint64_t cdiv_byp       : 1;
-               uint64_t sd_mode        : 2;
-               uint64_t s_bist         : 1;
-               uint64_t por            : 1;
-               uint64_t enable         : 1;
-               uint64_t prst           : 1;
-               uint64_t hrst           : 1;
-               uint64_t divide         : 3;
-       } s;
-       /**
-        * struct cvmx_usbnx_clk_ctl_cn30xx
-        * @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_rclk: Phy refrence clock enable.
-        *      '1' The PHY PLL uses the XO block output as a
-        *      reference.
-        *      '0' Reserved.
-        * @p_xenbn: Phy external clock enable.
-        *      '1' The XO block uses the clock from a crystal.
-        *      '0' The XO block uses an external clock supplied
-        *      on the XO pin. USB_XI should be tied to
-        *      ground for this usage.
-        * @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
-        *      '01': 24 MHz
-        *      '00': 12 MHz
-        *      The value of this field must be set while POR is
-        *      active.
-        * @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.
-        * @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 'hclk' used by the USB subsystem is derived
-        *      from the eclk. The eclk will be divided by the
-        *      value of this field +1 to determine the hclk
-        *      frequency. (Also see HRST of this register).
-        *      The hclk frequency must be less than 125 MHz.
-        */
-       struct cvmx_usbnx_clk_ctl_cn30xx {
-               uint64_t reserved_18_63 : 46;
-               uint64_t hclk_rst       : 1;
-               uint64_t p_x_on         : 1;
-               uint64_t p_rclk         : 1;
-               uint64_t p_xenbn        : 1;
-               uint64_t p_com_on       : 1;
-               uint64_t p_c_sel        : 2;
-               uint64_t cdiv_byp       : 1;
-               uint64_t sd_mode        : 2;
-               uint64_t s_bist         : 1;
-               uint64_t por            : 1;
-               uint64_t enable         : 1;
-               uint64_t prst           : 1;
-               uint64_t hrst           : 1;
-               uint64_t divide         : 3;
-       } cn30xx;
-       struct cvmx_usbnx_clk_ctl_cn30xx cn31xx;
-       /**
-        * struct cvmx_usbnx_clk_ctl_cn50xx
-        * @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_rtype: PHY reference clock type
-        *      '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
-        *      (bit 14 was P_XENBN on 3xxx)
-        *      (bit 15 was P_RCLK on 3xxx)
-        * @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_cn50xx {
-               uint64_t reserved_20_63 : 44;
-               uint64_t divide2        : 2;
-               uint64_t hclk_rst       : 1;
-               uint64_t reserved_16_16 : 1;
-               uint64_t p_rtype        : 2;
-               uint64_t p_com_on       : 1;
-               uint64_t p_c_sel        : 2;
-               uint64_t cdiv_byp       : 1;
-               uint64_t sd_mode        : 2;
-               uint64_t s_bist         : 1;
-               uint64_t por            : 1;
-               uint64_t enable         : 1;
-               uint64_t prst           : 1;
-               uint64_t hrst           : 1;
-               uint64_t divide         : 3;
-       } cn50xx;
-       struct cvmx_usbnx_clk_ctl_cn50xx cn52xx;
-       struct cvmx_usbnx_clk_ctl_cn50xx cn56xx;
-};
-
-/**
- * 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 {
-       uint64_t 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 Impedence 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 internaly 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 opeartion.
-        * @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 opeartion.
-        * @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' internaly 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-eanable 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 {
-               uint64_t txrisetune             : 1;
-               uint64_t txvreftune             : 4;
-               uint64_t txfslstune             : 4;
-               uint64_t txhsxvtune             : 2;
-               uint64_t sqrxtune               : 3;
-               uint64_t compdistune            : 3;
-               uint64_t otgtune                : 3;
-               uint64_t otgdisable             : 1;
-               uint64_t portreset              : 1;
-               uint64_t drvvbus                : 1;
-               uint64_t lsbist                 : 1;
-               uint64_t fsbist                 : 1;
-               uint64_t hsbist                 : 1;
-               uint64_t bist_done              : 1;
-               uint64_t bist_err               : 1;
-               uint64_t tdata_out              : 4;
-               uint64_t siddq                  : 1;
-               uint64_t txpreemphasistune      : 1;
-               uint64_t dma_bmode              : 1;
-               uint64_t usbc_end               : 1;
-               uint64_t usbp_bist              : 1;
-               uint64_t tclk                   : 1;
-               uint64_t dp_pulld               : 1;
-               uint64_t dm_pulld               : 1;
-               uint64_t hst_mode               : 1;
-               uint64_t tuning                 : 4;
-               uint64_t tx_bs_enh              : 1;
-               uint64_t tx_bs_en               : 1;
-               uint64_t loop_enb               : 1;
-               uint64_t vtest_enb              : 1;
-               uint64_t bist_enb               : 1;
-               uint64_t tdata_sel              : 1;
-               uint64_t taddr_in               : 4;
-               uint64_t tdata_in               : 8;
-               uint64_t ate_reset              : 1;
-       } s;
-       /**
-        * struct cvmx_usbnx_usbp_ctl_status_cn30xx
-        * @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 internaly generated signals or
-        *      test register contents, based upon the value of
-        *      test_data_out_sel.
-        * @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 opeartion.
-        * @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 opeartion.
-        * @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' internaly 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-eanable 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_cn30xx {
-               uint64_t reserved_38_63 : 26;
-               uint64_t bist_done      : 1;
-               uint64_t bist_err       : 1;
-               uint64_t tdata_out      : 4;
-               uint64_t reserved_30_31 : 2;
-               uint64_t dma_bmode      : 1;
-               uint64_t usbc_end       : 1;
-               uint64_t usbp_bist      : 1;
-               uint64_t tclk           : 1;
-               uint64_t dp_pulld       : 1;
-               uint64_t dm_pulld       : 1;
-               uint64_t hst_mode       : 1;
-               uint64_t tuning         : 4;
-               uint64_t tx_bs_enh      : 1;
-               uint64_t tx_bs_en       : 1;
-               uint64_t loop_enb       : 1;
-               uint64_t vtest_enb      : 1;
-               uint64_t bist_enb       : 1;
-               uint64_t tdata_sel      : 1;
-               uint64_t taddr_in       : 4;
-               uint64_t tdata_in       : 8;
-               uint64_t ate_reset      : 1;
-       } cn30xx;
-       /**
-        * struct cvmx_usbnx_usbp_ctl_status_cn50xx
-        * @txrisetune: HS Transmitter Rise/Fall Time Adjustment
-        * @txvreftune: HS DC Voltage Level Adjustment
-        * @txfslstune: FS/LS Source Impedence 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 internaly generated signals or
-        *      test register contents, based upon the value of
-        *      test_data_out_sel.
-        * @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 opeartion.
-        * @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 opeartion.
-        * @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.
-        * @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' internaly 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-eanable 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_cn50xx {
-               uint64_t txrisetune             : 1;
-               uint64_t txvreftune             : 4;
-               uint64_t txfslstune             : 4;
-               uint64_t txhsxvtune             : 2;
-               uint64_t sqrxtune               : 3;
-               uint64_t compdistune            : 3;
-               uint64_t otgtune                : 3;
-               uint64_t otgdisable             : 1;
-               uint64_t portreset              : 1;
-               uint64_t drvvbus                : 1;
-               uint64_t lsbist                 : 1;
-               uint64_t fsbist                 : 1;
-               uint64_t hsbist                 : 1;
-               uint64_t bist_done              : 1;
-               uint64_t bist_err               : 1;
-               uint64_t tdata_out              : 4;
-               uint64_t reserved_31_31         : 1;
-               uint64_t txpreemphasistune      : 1;
-               uint64_t dma_bmode              : 1;
-               uint64_t usbc_end               : 1;
-               uint64_t usbp_bist              : 1;
-               uint64_t tclk                   : 1;
-               uint64_t dp_pulld               : 1;
-               uint64_t dm_pulld               : 1;
-               uint64_t hst_mode               : 1;
-               uint64_t reserved_19_22         : 4;
-               uint64_t tx_bs_enh              : 1;
-               uint64_t tx_bs_en               : 1;
-               uint64_t loop_enb               : 1;
-               uint64_t vtest_enb              : 1;
-               uint64_t bist_enb               : 1;
-               uint64_t tdata_sel              : 1;
-               uint64_t taddr_in               : 4;
-               uint64_t tdata_in               : 8;
-               uint64_t ate_reset              : 1;
-       } cn50xx;
-       /**
-        * struct cvmx_usbnx_usbp_ctl_status_cn52xx
-        * @txrisetune: HS Transmitter Rise/Fall Time Adjustment
-        * @txvreftune: HS DC Voltage Level Adjustment
-        * @txfslstune: FS/LS Source Impedence 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 internaly 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 opeartion.
-        * @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 opeartion.
-        * @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.
-        * @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' internaly 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-eanable 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_cn52xx {
-               uint64_t txrisetune             : 1;
-               uint64_t txvreftune             : 4;
-               uint64_t txfslstune             : 4;
-               uint64_t txhsxvtune             : 2;
-               uint64_t sqrxtune               : 3;
-               uint64_t compdistune            : 3;
-               uint64_t otgtune                : 3;
-               uint64_t otgdisable             : 1;
-               uint64_t portreset              : 1;
-               uint64_t drvvbus                : 1;
-               uint64_t lsbist                 : 1;
-               uint64_t fsbist                 : 1;
-               uint64_t hsbist                 : 1;
-               uint64_t bist_done              : 1;
-               uint64_t bist_err               : 1;
-               uint64_t tdata_out              : 4;
-               uint64_t siddq                  : 1;
-               uint64_t txpreemphasistune      : 1;
-               uint64_t dma_bmode              : 1;
-               uint64_t usbc_end               : 1;
-               uint64_t usbp_bist              : 1;
-               uint64_t tclk                   : 1;
-               uint64_t dp_pulld               : 1;
-               uint64_t dm_pulld               : 1;
-               uint64_t hst_mode               : 1;
-               uint64_t reserved_19_22         : 4;
-               uint64_t tx_bs_enh              : 1;
-               uint64_t tx_bs_en               : 1;
-               uint64_t loop_enb               : 1;
-               uint64_t vtest_enb              : 1;
-               uint64_t bist_enb               : 1;
-               uint64_t tdata_sel              : 1;
-               uint64_t taddr_in               : 4;
-               uint64_t tdata_in               : 8;
-               uint64_t ate_reset              : 1;
-       } cn52xx;
-};
-
-#endif
index 5dbbd14ec615aba59d16c72a2e7acbe08f9073cf..d118952c0a74c9ff7d59597ccf76e5a16a4bd60d 100644 (file)
@@ -4,6 +4,44 @@
  * 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/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 
 #include <asm/octeon/cvmx.h>
-#include "cvmx-usb.h"
 #include <asm/octeon/cvmx-iob-defs.h>
 
 #include <linux/usb/hcd.h>
 
 #include <linux/err.h>
 
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-sysinfo.h>
+#include <asm/octeon/cvmx-helper-board.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_complete - possible callback function status codes
+ *
+ * @CVMX_USB_COMPLETE_SUCCESS:   The transaction / operation finished without
+ *                               any errors
+ * @CVMX_USB_COMPLETE_SHORT:     FIXME: This is currently not implemented
+ * @CVMX_USB_COMPLETE_CANCEL:    The transaction was canceled while in flight
+ *                               by a user call to cvmx_usb_cancel
+ * @CVMX_USB_COMPLETE_ERROR:     The transaction aborted with an unexpected
+ *                               error status
+ * @CVMX_USB_COMPLETE_STALL:     The transaction received a USB STALL response
+ *                               from the device
+ * @CVMX_USB_COMPLETE_XACTERR:   The transaction failed with an error from the
+ *                               device even after a number of retries
+ * @CVMX_USB_COMPLETE_DATATGLERR: The transaction failed with a data toggle
+ *                               error even after a number of retries
+ * @CVMX_USB_COMPLETE_BABBLEERR:  The transaction failed with a babble error
+ * @CVMX_USB_COMPLETE_FRAMEERR:          The transaction failed with a frame error
+ *                               even after a number of retries
+ */
+enum cvmx_usb_complete {
+       CVMX_USB_COMPLETE_SUCCESS,
+       CVMX_USB_COMPLETE_SHORT,
+       CVMX_USB_COMPLETE_CANCEL,
+       CVMX_USB_COMPLETE_ERROR,
+       CVMX_USB_COMPLETE_STALL,
+       CVMX_USB_COMPLETE_XACTERR,
+       CVMX_USB_COMPLETE_DATATGLERR,
+       CVMX_USB_COMPLETE_BABBLEERR,
+       CVMX_USB_COMPLETE_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 {
+       uint32_t reserved               : 25;
+       uint32_t port_enabled           : 1;
+       uint32_t port_over_current      : 1;
+       uint32_t port_powered           : 1;
+       enum cvmx_usb_speed port_speed  : 2;
+       uint32_t connected              : 1;
+       uint32_t connect_change         : 1;
+};
+
+/**
+ * union cvmx_usb_control_header - the structure of a Control packet header
+ *
+ * @s.request_type:    Bit 7 tells the direction: 1=IN, 0=OUT
+ * @s.request          The standard usb request to make
+ * @s.value            Value parameter for the request in little endian format
+ * @s.index            Index for the request in little endian format
+ * @s.length           Length of the data associated with this request in
+ *                     little endian format
+ */
+union cvmx_usb_control_header {
+       uint64_t u64;
+       struct {
+               uint64_t request_type   : 8;
+               uint64_t request        : 8;
+               uint64_t value          : 16;
+               uint64_t index          : 16;
+               uint64_t length         : 16;
+       } s;
+};
+
+/**
+ * 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_complete 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. Do not use.
+ * @__CVMX_USB_PIPE_FLAGS_NEED_PING: Used internally to determine if a high
+ *                                  speed pipe is in the ping state. Do not
+ *                                  use.
+ */
+enum cvmx_usb_pipe_flags {
+       __CVMX_USB_PIPE_FLAGS_SCHEDULED = 1 << 17,
+       __CVMX_USB_PIPE_FLAGS_NEED_PING = 1 << 18,
+};
+
+/* Normal prefetch that use the pref instruction. */
+#define CVMX_PREFETCH(address, offset) asm volatile ("pref %[type], %[off](%[rbase])" : : [rbase] "d" (address), [off] "I" (offset), [type] "n" (0))
+
+/* 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 highest valid USB device address */
+#define MAX_USB_ADDRESS                127
+
+/* The highest valid USB endpoint number */
+#define MAX_USB_ENDPOINT       15
+
+/* The highest valid port number on a hub */
+#define MAX_USB_HUB_PORT       15
+
+/*
+ * 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)
+
+enum {
+       USB_CLOCK_TYPE_REF_12,
+       USB_CLOCK_TYPE_REF_24,
+       USB_CLOCK_TYPE_REF_48,
+       USB_CLOCK_TYPE_CRYSTAL_12,
+};
+
+/**
+ * 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;
+       uint64_t buffer;
+       int buffer_length;
+       uint64_t 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;
+       uint64_t interval;
+       uint64_t 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;
+       uint16_t max_packet;
+       uint8_t device_addr;
+       uint8_t endpoint_num;
+       uint8_t hub_device_addr;
+       uint8_t hub_port;
+       uint8_t pid_toggle;
+       uint8_t channel;
+       int8_t split_sc_frame;
+};
+
+struct cvmx_usb_tx_fifo {
+       struct {
+               int channel;
+               int size;
+               uint64_t address;
+       } entry[MAX_CHANNELS+1];
+       int head;
+       int tail;
+};
+
+/**
+ * struct cvmx_usb_state - the state of the USB block
+ *
+ * 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 cvmx_usb_state {
+       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];
+       uint64_t frame_number;
+       struct cvmx_usb_transaction *active_split;
+       struct cvmx_usb_tx_fifo periodic;
+       struct cvmx_usb_tx_fifo nonperiodic;
+};
+
 struct octeon_hcd {
        spinlock_t lock;
        struct cvmx_usb_state usb;
@@ -31,173 +435,2569 @@ struct octeon_hcd {
        struct list_head dequeue_list;
 };
 
-/* convert between an HCD pointer and the corresponding struct octeon_hcd */
-static inline struct octeon_hcd *hcd_to_octeon(struct usb_hcd *hcd)
+/* This macro spins on a field waiting for it to reach a value */
+#define CVMX_WAIT_FOR_FIELD32(address, type, field, op, value, timeout_usec)\
+       ({int result;                                                       \
+       do {                                                                \
+               uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \
+                       octeon_get_clock_rate() / 1000000;                  \
+               type c;                                                     \
+               while (1) {                                                 \
+                       c.u32 = __cvmx_usb_read_csr32(usb, address);        \
+                       if (c.s.field op (value)) {                         \
+                               result = 0;                                 \
+                               break;                                      \
+                       } else if (cvmx_get_cycle() > done) {               \
+                               result = -1;                                \
+                               break;                                      \
+                       } else                                              \
+                               cvmx_wait(100);                             \
+               }                                                           \
+       } while (0);                                                        \
+       result; })
+
+/*
+ * This macro logically sets a single field in a CSR. It does the sequence
+ * read, modify, and write
+ */
+#define USB_SET_FIELD32(address, type, field, value)           \
+       do {                                                    \
+               type 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)
+
+static int octeon_usb_get_clock_type(void)
 {
-       return (struct octeon_hcd *)(hcd->hcd_priv);
+       switch (cvmx_sysinfo_get()->board_type) {
+       case CVMX_BOARD_TYPE_BBGW_REF:
+       case CVMX_BOARD_TYPE_LANAI2_A:
+       case CVMX_BOARD_TYPE_LANAI2_U:
+       case CVMX_BOARD_TYPE_LANAI2_G:
+       case CVMX_BOARD_TYPE_UBNT_E100:
+               return USB_CLOCK_TYPE_CRYSTAL_12;
+       }
+       return USB_CLOCK_TYPE_REF_48;
 }
 
-static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p)
+/**
+ * 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 uint32_t __cvmx_usb_read_csr32(struct cvmx_usb_state *usb,
+                                            uint64_t address)
 {
-       return container_of((void *)p, struct usb_hcd, hcd_priv);
+       uint32_t result = cvmx_read64_uint32(address ^ 4);
+       return result;
 }
 
-static inline struct octeon_hcd *cvmx_usb_to_octeon(struct cvmx_usb_state *p)
+
+/**
+ * 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 cvmx_usb_state *usb,
+                                         uint64_t address, uint32_t value)
 {
-       return container_of(p, struct octeon_hcd, usb);
+       cvmx_write64_uint32(address ^ 4, value);
+       cvmx_read64_uint64(CVMX_USBNX_DMA0_INB_CHN0(usb->index));
 }
 
-static irqreturn_t octeon_usb_irq(struct usb_hcd *hcd)
-{
-       struct octeon_hcd *priv = hcd_to_octeon(hcd);
-       unsigned long flags;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       cvmx_usb_poll(&priv->usb);
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return IRQ_HANDLED;
+/**
+ * Read a USB 64bit CSR. It 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 uint64_t __cvmx_usb_read_csr64(struct cvmx_usb_state *usb,
+                                            uint64_t address)
+{
+       uint64_t result = cvmx_read64_uint64(address);
+       return result;
 }
 
-static void octeon_usb_port_callback(struct cvmx_usb_state *usb,
-                                    enum cvmx_usb_callback reason,
-                                    enum cvmx_usb_complete status,
-                                    int pipe_handle,
-                                    int submit_handle,
-                                    int bytes_transferred,
-                                    void *user_data)
-{
-       struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
 
-       spin_unlock(&priv->lock);
-       usb_hcd_poll_rh_status(octeon_to_hcd(priv));
-       spin_lock(&priv->lock);
+/**
+ * Write a USB 64bit CSR. It 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_csr64(struct cvmx_usb_state *usb,
+                                         uint64_t address, uint64_t value)
+{
+       cvmx_write64_uint64(address, value);
 }
 
-static int octeon_usb_start(struct usb_hcd *hcd)
+/**
+ * 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 cvmx_usb_state *usb,
+                                             struct cvmx_usb_pipe *pipe)
 {
-       struct octeon_hcd *priv = hcd_to_octeon(hcd);
-       unsigned long flags;
-
-       hcd->state = HC_STATE_RUNNING;
-       spin_lock_irqsave(&priv->lock, flags);
-       cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED,
-                                  octeon_usb_port_callback, NULL);
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return 0;
+       return pipe->device_speed != CVMX_USB_SPEED_HIGH &&
+              usb->usbcx_hprt.s.prtspd == CVMX_USB_SPEED_HIGH;
 }
 
-static void octeon_usb_stop(struct usb_hcd *hcd)
-{
-       struct octeon_hcd *priv = hcd_to_octeon(hcd);
-       unsigned long flags;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       cvmx_usb_register_callback(&priv->usb, CVMX_USB_CALLBACK_PORT_CHANGED,
-                                  NULL, NULL);
-       spin_unlock_irqrestore(&priv->lock, flags);
-       hcd->state = HC_STATE_HALT;
+/**
+ * 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 */
+       else
+               return 0; /* Data0 */
 }
 
-static int octeon_usb_get_frame_number(struct usb_hcd *hcd)
-{
-       struct octeon_hcd *priv = hcd_to_octeon(hcd);
 
-       return cvmx_usb_get_frame_number(&priv->usb);
+/**
+ * Return the number of USB ports supported by this Octeon
+ * chip. If the chip doesn't support USB, or is not supported
+ * by this API, a zero will be returned. Most Octeon chips
+ * support one usb port, but some support two ports.
+ * cvmx_usb_initialize() must be called on independent
+ * struct cvmx_usb_state.
+ *
+ * Returns: Number of port, zero if usb isn't supported
+ */
+static int cvmx_usb_get_num_ports(void)
+{
+       int arch_ports = 0;
+
+       if (OCTEON_IS_MODEL(OCTEON_CN56XX))
+               arch_ports = 1;
+       else if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+               arch_ports = 2;
+       else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
+               arch_ports = 1;
+       else if (OCTEON_IS_MODEL(OCTEON_CN31XX))
+               arch_ports = 1;
+       else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
+               arch_ports = 1;
+       else
+               arch_ports = 0;
+
+       return arch_ports;
 }
 
-static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
-                                            enum cvmx_usb_callback reason,
-                                            enum cvmx_usb_complete status,
-                                            int pipe_handle,
-                                            int submit_handle,
-                                            int bytes_transferred,
-                                            void *user_data)
+/**
+ * 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.
+ *
+ * @usb:        Pointer to an empty struct cvmx_usb_state
+ *              that will be populated by the initialize call.
+ *              This structure is then passed to all other USB
+ *              functions.
+ * @usb_port_number:
+ *              Which Octeon USB port to initialize.
+ *
+ * Returns: 0 or a negative error code.
+ */
+static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
+                              int usb_port_number)
 {
-       struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
-       struct usb_hcd *hcd = octeon_to_hcd(priv);
-       struct device *dev = hcd->self.controller;
-       struct urb *urb = user_data;
+       union cvmx_usbnx_clk_ctl usbn_clk_ctl;
+       union cvmx_usbnx_usbp_ctl_status usbn_usbp_ctl_status;
+       enum cvmx_usb_initialize_flags flags = 0;
+       int i;
 
-       urb->actual_length = bytes_transferred;
-       urb->hcpriv = NULL;
+       /* At first allow 0-1 for the usb port number */
+       if ((usb_port_number < 0) || (usb_port_number > 1))
+               return -EINVAL;
+       /* For all chips except 52XX there is only one port */
+       if (!OCTEON_IS_MODEL(OCTEON_CN52XX) && (usb_port_number > 0))
+               return -EINVAL;
+       /* Try to determine clock type automatically */
+       if (octeon_usb_get_clock_type() == USB_CLOCK_TYPE_CRYSTAL_12) {
+               /* Only 12 MHZ crystals are supported */
+               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_XI;
+       } else {
+               flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_XO_GND;
+
+               switch (octeon_usb_get_clock_type()) {
+               case USB_CLOCK_TYPE_REF_12:
+                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ;
+                       break;
+               case USB_CLOCK_TYPE_REF_24:
+                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_24MHZ;
+                       break;
+               case USB_CLOCK_TYPE_REF_48:
+                       flags |= CVMX_USB_INITIALIZE_FLAGS_CLOCK_48MHZ;
+                       break;
+               default:
+                       return -EINVAL;
+                       break;
+               }
+       }
 
-       if (!list_empty(&urb->urb_list)) {
+       memset(usb, 0, sizeof(*usb));
+       usb->init_flags = flags;
+
+       /* Initialize the USB state structure */
+       usb->index = usb_port_number;
+       INIT_LIST_HEAD(&usb->idle_pipes);
+       for (i = 0; i < ARRAY_SIZE(usb->active_pipes); i++)
+               INIT_LIST_HEAD(&usb->active_pipes[i]);
+
+       /*
+        * 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_usb_read_csr64(usb, 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) {
                /*
-                * It is on the dequeue_list, but we are going to call
-                * usb_hcd_giveback_urb(), so we must clear it from
-                * the list.  We got to it before the
-                * octeon_usb_urb_dequeue_work() tasklet did.
+                * 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 (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
+        */
+       {
+               int divisor = (octeon_get_clock_rate()+125000000-1)/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_usb_write_csr64(usb, 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_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
+                              usbn_clk_ctl.u64);
+       /* 2e.  Wait 64 core-clock cycles for HCLK to stabilize */
+       cvmx_wait(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_usb_write_csr64(usb, 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_usb_read_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index));
+       usbn_usbp_ctl_status.s.ate_reset = 1;
+       __cvmx_usb_write_csr64(usb, CVMX_USBNX_USBP_CTL_STATUS(usb->index),
+                              usbn_usbp_ctl_status.u64);
+       /* 6. Wait 10 cycles */
+       cvmx_wait(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_usb_write_csr64(usb, 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_usb_write_csr64(usb, 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_usb_write_csr64(usb, 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_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
+                              usbn_clk_ctl.u64);
+       /* 12. Proceed to USB core initialization */
+       usbn_clk_ctl.s.enable = 1;
+       __cvmx_usb_write_csr64(usb, 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
+        */
+       {
+               union cvmx_usbcx_gahbcfg usbcx_gahbcfg;
+               /* Due to an errata, CN31XX doesn't support DMA */
+               if (OCTEON_IS_MODEL(OCTEON_CN31XX))
+                       usb->init_flags |= CVMX_USB_INITIALIZE_FLAGS_NO_DMA;
+               usbcx_gahbcfg.u32 = 0;
+               usbcx_gahbcfg.s.dmaen = !(usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA);
+               if (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;
+               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
+        */
+       {
+               union cvmx_usbcx_gusbcfg usbcx_gusbcfg;
+               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
+        */
+       {
+               union cvmx_usbcx_gintmsk usbcx_gintmsk;
+               int channel;
+
+               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.
                 */
-               list_del(&urb->urb_list);
-               /* No longer on the dequeue_list. */
-               INIT_LIST_HEAD(&urb->urb_list);
+               for (channel = 0; channel < 8; channel++)
+                       __cvmx_usb_write_csr32(usb, CVMX_USBCX_HCINTMSKX(channel, usb->index), 0);
        }
 
-       /* 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.
+                * Host Port Initialization
+                *
+                * 1. Program the host-port interrupt-mask field to unmask,
+                *    USBC_GINTMSK[PRTINT] = 1
                 */
-               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_COMPLETE_SUCCESS) {
-                               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=%d submit=%d size=%d\n",
-                                       i, urb->number_of_packets,
-                                       iso_packet[i].status, pipe_handle,
-                                       submit_handle, iso_packet[i].length);
-                               urb->iso_frame_desc[i].status = -EREMOTEIO;
-                       }
+               USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk,
+                               prtintmsk, 1);
+               USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk,
+                               disconnintmsk, 1);
+               /*
+                * 2. Program the USBC_HCFG register to select full-speed host
+                *    or high-speed host.
+                */
+               {
+                       union cvmx_usbcx_hcfg usbcx_hcfg;
+                       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);
                }
-               /* Free the private list now that we don't need it anymore */
-               kfree(iso_packet);
-               urb->setup_packet = NULL;
+               /*
+                * 3. Program the port power bit to drive VBUS on the USB,
+                *    USBC_HPRT[PRTPWR] = 1
+                */
+               USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt, prtpwr, 1);
+
+               /*
+                * Steps 4-15 from the manual are done later in the port enable
+                */
        }
 
-       switch (status) {
-       case CVMX_USB_COMPLETE_SUCCESS:
-               urb->status = 0;
-               break;
-       case CVMX_USB_COMPLETE_CANCEL:
-               if (urb->status == 0)
-                       urb->status = -ENOENT;
-               break;
-       case CVMX_USB_COMPLETE_STALL:
-               dev_dbg(dev, "status=stall pipe=%d submit=%d size=%d\n",
-                       pipe_handle, submit_handle, bytes_transferred);
-               urb->status = -EPIPE;
+       return 0;
+}
+
+
+/**
+ * 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 cvmx_usb_state *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_usb_read_csr64(usb, 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_usb_write_csr64(usb, CVMX_USBNX_CLK_CTL(usb->index),
+                              usbn_clk_ctl.u64);
+       return 0;
+}
+
+
+/**
+ * Enable a USB port. After this call succeeds, the USB port is
+ * online and servicing requests.
+ *
+ * @usb: USB device state populated by cvmx_usb_initialize().
+ *
+ * Returns: 0 or a negative error code.
+ */
+static int cvmx_usb_enable(struct cvmx_usb_state *usb)
+{
+       union cvmx_usbcx_ghwcfg3 usbcx_ghwcfg3;
+
+       usb->usbcx_hprt.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPRT(usb->index));
+
+       /*
+        * If the port is already enabled the just return. We don't need to do
+        * anything
+        */
+       if (usb->usbcx_hprt.s.prtena)
+               return 0;
+
+       /* If there is nothing plugged into the port then fail immediately */
+       if (!usb->usbcx_hprt.s.prtconnsts) {
+               return -ETIMEDOUT;
+       }
+
+       /* Program the port reset bit to start the reset process */
+       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union 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), union cvmx_usbcx_hprt, prtrst, 0);
+
+       /* Wait for the USBC_HPRT[PRTENA]. */
+       if (CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_HPRT(usb->index), union cvmx_usbcx_hprt,
+                                 prtena, ==, 1, 100000))
+               return -ETIMEDOUT;
+
+       /*
+        * 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));
+       usbcx_ghwcfg3.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GHWCFG3(usb->index));
+
+       /*
+        * 13. Program the USBC_GRXFSIZ register to select the size of the
+        *     receive FIFO (25%).
+        */
+       USB_SET_FIELD32(CVMX_USBCX_GRXFSIZ(usb->index), union cvmx_usbcx_grxfsiz,
+                       rxfdep, usbcx_ghwcfg3.s.dfifodepth / 4);
+       /*
+        * 14. Program the USBC_GNPTXFSIZ register to select the size and the
+        *     start address of the non- periodic transmit FIFO for nonperiodic
+        *     transactions (50%).
+        */
+       {
+               union cvmx_usbcx_gnptxfsiz siz;
+               siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index));
+               siz.s.nptxfdep = usbcx_ghwcfg3.s.dfifodepth / 2;
+               siz.s.nptxfstaddr = usbcx_ghwcfg3.s.dfifodepth / 4;
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_GNPTXFSIZ(usb->index), siz.u32);
+       }
+       /*
+        * 15. Program the USBC_HPTXFSIZ register to select the size and start
+        *     address of the periodic transmit FIFO for periodic transactions
+        *     (25%).
+        */
+       {
+               union cvmx_usbcx_hptxfsiz siz;
+               siz.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index));
+               siz.s.ptxfsize = usbcx_ghwcfg3.s.dfifodepth / 4;
+               siz.s.ptxfstaddr = 3 * usbcx_ghwcfg3.s.dfifodepth / 4;
+               __cvmx_usb_write_csr32(usb, CVMX_USBCX_HPTXFSIZ(usb->index), siz.u32);
+       }
+       /* Flush all FIFOs */
+       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, txfnum, 0x10);
+       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, txfflsh, 1);
+       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl,
+                             txfflsh, ==, 0, 100);
+       USB_SET_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl, rxfflsh, 1);
+       CVMX_WAIT_FOR_FIELD32(CVMX_USBCX_GRSTCTL(usb->index), union cvmx_usbcx_grstctl,
+                             rxfflsh, ==, 0, 100);
+
+       return 0;
+}
+
+
+/**
+ * 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 cvmx_usb_state *usb)
+{
+       /* Disable the port */
+       USB_SET_FIELD32(CVMX_USBCX_HPRT(usb->index), union 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 cvmx_usb_state *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 cvmx_usb_state *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;
+
+       if (unlikely((device_addr < 0) || (device_addr > MAX_USB_ADDRESS)))
+               return NULL;
+       if (unlikely((endpoint_num < 0) || (endpoint_num > MAX_USB_ENDPOINT)))
+               return NULL;
+       if (unlikely(device_speed > CVMX_USB_SPEED_LOW))
+               return NULL;
+       if (unlikely((max_packet <= 0) || (max_packet > 1024)))
+               return NULL;
+       if (unlikely(transfer_type > CVMX_USB_TRANSFER_INTERRUPT))
+               return NULL;
+       if (unlikely((transfer_dir != CVMX_USB_DIRECTION_OUT) &&
+               (transfer_dir != CVMX_USB_DIRECTION_IN)))
+               return NULL;
+       if (unlikely(interval < 0))
+               return NULL;
+       if (unlikely((transfer_type == CVMX_USB_TRANSFER_CONTROL) && interval))
+               return NULL;
+       if (unlikely(multi_count < 0))
+               return NULL;
+       if (unlikely((device_speed != CVMX_USB_SPEED_HIGH) &&
+               (multi_count != 0)))
+               return NULL;
+       if (unlikely((hub_device_addr < 0) || (hub_device_addr > MAX_USB_ADDRESS)))
+               return NULL;
+       if (unlikely((hub_port < 0) || (hub_port > MAX_USB_HUB_PORT)))
+               return NULL;
+
+       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 cvmx_usb_state *usb)
+{
+       union cvmx_usbcx_grxstsph rx_status;
+       int channel;
+       int bytes;
+       uint64_t address;
+       uint32_t *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_usb_read_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + channel*8);
+       ptr = cvmx_phys_to_ptr(address);
+       __cvmx_usb_write_csr64(usb, 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;
+
+       return;
+}
+
+
+/**
+ * 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 cvmx_usb_state *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 uint32_t *ptr = cvmx_phys_to_ptr(fifo->entry[i].address);
+               uint64_t csr_address = USB_FIFO_ADDRESS(fifo->entry[i].channel, usb->index) ^ 4;
+               int words = available;
+
+               /* Limit the amount of data to waht 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 cvmx_usb_state *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), union cvmx_usbcx_gintmsk, ptxfempmsk, 1);
+               else
+                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union 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), union cvmx_usbcx_gintmsk, nptxfempmsk, 1);
+               else
+                       USB_SET_FIELD32(CVMX_USBCX_GINTMSK(usb->index), union cvmx_usbcx_gintmsk, nptxfempmsk, 0);
+       }
+
+       return;
+}
+
+
+/**
+ * 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 cvmx_usb_state *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_usb_read_csr64(usb, 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);
+
+       return;
+}
+
+/**
+ * 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 cvmx_usb_state *usb,
+                                            int channel,
+                                            struct cvmx_usb_pipe *pipe)
+{
+       struct cvmx_usb_transaction *transaction =
+               list_first_entry(&pipe->transactions, typeof(*transaction),
+                                node);
+       union cvmx_usb_control_header *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:
+               cvmx_dprintf("%s: ERROR - Non control stage\n", __FUNCTION__);
                break;
-       case CVMX_USB_COMPLETE_BABBLEERR:
-               dev_dbg(dev, "status=babble pipe=%d submit=%d size=%d\n",
-                       pipe_handle, submit_handle, bytes_transferred);
-               urb->status = -EPIPE;
+       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), union 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_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, transaction->control_header);
                break;
-       case CVMX_USB_COMPLETE_SHORT:
-               dev_dbg(dev, "status=short pipe=%d submit=%d size=%d\n",
-                       pipe_handle, submit_handle, bytes_transferred);
-               urb->status = -EREMOTEIO;
+       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), union cvmx_usbcx_hccharx, epdir, CVMX_USB_DIRECTION_OUT);
+               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
                break;
-       case CVMX_USB_COMPLETE_ERROR:
-       case CVMX_USB_COMPLETE_XACTERR:
-       case CVMX_USB_COMPLETE_DATATGLERR:
-       case CVMX_USB_COMPLETE_FRAMEERR:
-               dev_dbg(dev, "status=%d pipe=%d submit=%d size=%d\n",
-                       status, pipe_handle, submit_handle, bytes_transferred);
-               urb->status = -EPROTO;
+       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->s.request_type & 0x80)
+                               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),
+                               union cvmx_usbcx_hccharx, epdir,
+                               ((header->s.request_type & 0x80) ?
+                                       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->s.request_type & 0x80))
+                       bytes_to_transfer = 0;
+               USB_SET_FIELD32(CVMX_USBCX_HCCHARX(channel, usb->index),
+                               union cvmx_usbcx_hccharx, epdir,
+                               ((header->s.request_type & 0x80) ?
+                                       CVMX_USB_DIRECTION_IN :
+                                       CVMX_USB_DIRECTION_OUT));
+               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union 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), union cvmx_usbcx_hccharx, epdir,
+                               ((header->s.request_type & 0x80) ?
+                                       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), union cvmx_usbcx_hccharx, epdir,
+                               ((header->s.request_type & 0x80) ?
+                                       CVMX_USB_DIRECTION_OUT :
+                                       CVMX_USB_DIRECTION_IN));
+               USB_SET_FIELD32(CVMX_USBCX_HCSPLTX(channel, usb->index), union cvmx_usbcx_hcspltx, compsplt, 1);
                break;
        }
-       spin_unlock(&priv->lock);
-       usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status);
-       spin_lock(&priv->lock);
+
+       /*
+        * 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 = (bytes_to_transfer + pipe->max_packet - 1) / 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);
+       return;
+}
+
+
+/**
+ * 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 cvmx_usb_state *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 locations the DMA engines use  */
+       {
+               uint64_t 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;
+               __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_OUTB_CHN0(usb->index) + channel*8, dma_address);
+               __cvmx_usb_write_csr64(usb, CVMX_USBNX_DMA0_INB_CHN0(usb->index) + 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 = (bytes_to_transfer + pipe->max_packet - 1) / 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), union cvmx_usbcx_hctsizx, pid, 0);
+                               else /* Need MDATA */
+                                       USB_SET_FIELD32(CVMX_USBCX_HCTSIZX(channel, usb->index), union 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;
+       }
+       /* Remeber 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), union cvmx_usbcx_hccharx, chena, 1);
+       if (usb->init_flags & CVMX_USB_INITIALIZE_FLAGS_NO_DMA)
+               __cvmx_usb_fill_tx_fifo(usb, channel);
+       return;
+}
+
+
+/**
+ * Find a pipe that is ready to be scheduled to hardware.
+ * @usb:        USB device state populated by cvmx_usb_initialize().
+ * @list:       Pipe list to search
+ * @current_frame:
+ *              Frame counter to use as a time reference.
+ *
+ * Returns: Pipe or NULL if none are ready
+ */
+static struct cvmx_usb_pipe *__cvmx_usb_find_ready_pipe(struct cvmx_usb_state *usb, struct list_head *list, uint64_t current_frame)
+{
+       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 - (int)pipe->split_sc_frame) & 0x7f) < 0x40)) &&
+                       (!usb->active_split || (usb->active_split == t))) {
+                       CVMX_PREFETCH(pipe, 128);
+                       CVMX_PREFETCH(t, 0);
+                       return pipe;
+               }
+       }
+       return NULL;
+}
+
+
+/**
+ * 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 cvmx_usb_state *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;
+
+               /* Find a pipe needing service */
+               pipe = NULL;
+               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, usb->active_pipes + CVMX_USB_TRANSFER_ISOCHRONOUS, usb->frame_number);
+                       if (likely(!pipe))
+                               pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_INTERRUPT, usb->frame_number);
+               }
+               if (likely(!pipe)) {
+                       pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_CONTROL, usb->frame_number);
+                       if (likely(!pipe))
+                               pipe = __cvmx_usb_find_ready_pipe(usb, usb->active_pipes + CVMX_USB_TRANSFER_BULK, usb->frame_number);
+               }
+               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), union cvmx_usbcx_gintmsk, sofmsk, need_sof);
+       return;
+}
+
+static inline struct octeon_hcd *cvmx_usb_to_octeon(struct cvmx_usb_state *p)
+{
+       return container_of(p, struct octeon_hcd, usb);
+}
+
+static inline struct usb_hcd *octeon_to_hcd(struct octeon_hcd *p)
+{
+       return container_of((void *)p, struct usb_hcd, hcd_priv);
+}
+
+static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
+                                            enum cvmx_usb_complete status,
+                                            struct cvmx_usb_pipe *pipe,
+                                            struct cvmx_usb_transaction
+                                               *transaction,
+                                            int bytes_transferred,
+                                            struct urb *urb)
+{
+       struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
+       struct usb_hcd *hcd = octeon_to_hcd(priv);
+       struct device *dev = hcd->self.controller;
+
+       urb->actual_length = bytes_transferred;
+       urb->hcpriv = NULL;
+
+       if (!list_empty(&urb->urb_list))
+               /*
+                * It is on the dequeue_list, but we are going to call
+                * usb_hcd_giveback_urb(), so we must clear it from
+                * the list.  We got to it before the
+                * octeon_usb_urb_dequeue_work() tasklet did.
+                */
+               list_del_init(&urb->urb_list);
+
+       /* 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_COMPLETE_SUCCESS) {
+                               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_COMPLETE_SUCCESS:
+               urb->status = 0;
+               break;
+       case CVMX_USB_COMPLETE_CANCEL:
+               if (urb->status == 0)
+                       urb->status = -ENOENT;
+               break;
+       case CVMX_USB_COMPLETE_STALL:
+               dev_dbg(dev, "status=stall pipe=%p transaction=%p size=%d\n",
+                       pipe, transaction, bytes_transferred);
+               urb->status = -EPIPE;
+               break;
+       case CVMX_USB_COMPLETE_BABBLEERR:
+               dev_dbg(dev, "status=babble pipe=%p transaction=%p size=%d\n",
+                       pipe, transaction, bytes_transferred);
+               urb->status = -EPIPE;
+               break;
+       case CVMX_USB_COMPLETE_SHORT:
+               dev_dbg(dev, "status=short pipe=%p transaction=%p size=%d\n",
+                       pipe, transaction, bytes_transferred);
+               urb->status = -EREMOTEIO;
+               break;
+       case CVMX_USB_COMPLETE_ERROR:
+       case CVMX_USB_COMPLETE_XACTERR:
+       case CVMX_USB_COMPLETE_DATATGLERR:
+       case CVMX_USB_COMPLETE_FRAMEERR:
+               dev_dbg(dev, "status=%d pipe=%p transaction=%p size=%d\n",
+                       status, pipe, transaction, bytes_transferred);
+               urb->status = -EPROTO;
+               break;
+       }
+       spin_unlock(&priv->lock);
+       usb_hcd_giveback_urb(octeon_to_hcd(priv), urb, urb->status);
+       spin_lock(&priv->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_perform_complete(struct cvmx_usb_state *usb,
+                                       struct cvmx_usb_pipe *pipe,
+                                       struct cvmx_usb_transaction *transaction,
+                                       enum cvmx_usb_complete 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_COMPLETE_SUCCESS)) {
+                       /* 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;
+                       goto done;
+               }
+       }
+
+       /* 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);
+done:
+       return;
+}
+
+
+/**
+ * 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 cvmx_usb_state *usb,
+                                                                 struct cvmx_usb_pipe *pipe,
+                                                                 enum cvmx_usb_transfer type,
+                                                                 uint64_t buffer,
+                                                                 int buffer_length,
+                                                                 uint64_t 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 cvmx_usb_state *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 cvmx_usb_state *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 cvmx_usb_state *usb,
+                                                           struct cvmx_usb_pipe *pipe,
+                                                           struct urb *urb)
+{
+       int buffer_length = urb->transfer_buffer_length;
+       uint64_t control_header = urb->setup_dma;
+       union cvmx_usb_control_header *header =
+               cvmx_phys_to_ptr(control_header);
+
+       if ((header->s.request_type & 0x80) == 0)
+               buffer_length = le16_to_cpu(header->s.length);
+
+       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 cvmx_usb_state *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 cvmx_usb_state *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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_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 cvmx_usb_state *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 cvmx_usb_state *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 cvmx_usb_state *usb)
+{
+       int frame_number;
+       union cvmx_usbcx_hfnum usbc_hfnum;
+
+       usbc_hfnum.u32 = __cvmx_usb_read_csr32(usb, CVMX_USBCX_HFNUM(usb->index));
+       frame_number = usbc_hfnum.s.frnum;
+
+       return frame_number;
+}
+
+
+/**
+ * Poll a channel for status
+ *
+ * @usb:     USB device
+ * @channel: Channel to poll
+ *
+ * Returns: Zero on success
+ */
+static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
+{
+       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 {
+                               cvmx_dprintf("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];
+       CVMX_PREFETCH(pipe, 0);
+       CVMX_PREFETCH(pipe, 128);
+       if (!pipe)
+               return 0;
+       transaction = list_first_entry(&pipe->transactions, typeof(*transaction),
+                                      node);
+       CVMX_PREFETCH(transaction, 0);
+
+       /*
+        * 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
+        * transfered
+        */
+       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 (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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_STALL);
+       } else if (usbc_hcint.s.xacterr) {
+               /*
+                * We know at least one packet worked if we get a ACK or NAK.
+                * Reset the retry counter
+                */
+               if (usbc_hcint.s.nak || usbc_hcint.s.ack)
+                       transaction->retries = 0;
+               transaction->retries++;
+               if (transaction->retries > MAX_RETRIES) {
+                       /*
+                        * XactErr as a response means the device signaled
+                        * something wrong with the transfer. For example, PID
+                        * toggle errors cause these
+                        */
+                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_XACTERR);
+               } else {
+                       /*
+                        * If this was a split then clear our split in progress
+                        * marker
+                        */
+                       if (usb->active_split == transaction)
+                               usb->active_split = NULL;
+                       /*
+                        * Rewind to the beginning of the transaction by anding
+                        * off the split complete bit
+                        */
+                       transaction->stage &= ~1;
+                       pipe->split_sc_frame = -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 if (usbc_hcint.s.bblerr) {
+               /* Babble Error (BblErr) */
+               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_BABBLEERR);
+       } else if (usbc_hcint.s.datatglerr) {
+               /* We'll retry the exact same transaction again */
+               transaction->retries++;
+       } 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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+               } 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:
+                       switch (transaction->stage) {
+                       case CVMX_USB_STAGE_NON_CONTROL:
+                       case CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE:
+                               /* This should be impossible */
+                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_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 {
+                                       union cvmx_usb_control_header *header =
+                                               cvmx_phys_to_ptr(transaction->control_header);
+                                       if (header->s.length)
+                                               transaction->stage = CVMX_USB_STAGE_DATA;
+                                       else
+                                               transaction->stage = CVMX_USB_STAGE_STATUS;
+                               }
+                               break;
+                       case CVMX_USB_STAGE_SETUP_SPLIT_COMPLETE:
+                               {
+                                       union cvmx_usb_control_header *header =
+                                               cvmx_phys_to_ptr(transaction->control_header);
+                                       if (header->s.length)
+                                               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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                               break;
+                       case CVMX_USB_STAGE_STATUS_SPLIT_COMPLETE:
+                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                               break;
+                       }
+                       break;
+               case CVMX_USB_TRANSFER_BULK:
+               case CVMX_USB_TRANSFER_INTERRUPT:
+                       /*
+                        * 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 {
+                                               if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
+                                                       pipe->next_tx_frame += pipe->interval;
+                                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                                       }
+                               }
+                       } else {
+                               if ((pipe->device_speed == CVMX_USB_SPEED_HIGH) &&
+                                   (pipe->transfer_type == CVMX_USB_TRANSFER_BULK) &&
+                                   (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)) {
+                                       if (transaction->type == CVMX_USB_TRANSFER_INTERRUPT)
+                                               pipe->next_tx_frame += pipe->interval;
+                                       __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                               }
+                       }
+                       break;
+               case CVMX_USB_TRANSFER_ISOCHRONOUS:
+                       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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                                       }
+                               } else {
+                                       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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                                               }
+                                       } else
+                                               transaction->stage = CVMX_USB_STAGE_NON_CONTROL_SPLIT_COMPLETE;
+                               }
+                       } else {
+                               pipe->next_tx_frame += pipe->interval;
+                               __cvmx_usb_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_SUCCESS);
+                       }
+                       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_perform_complete(usb, pipe, transaction, CVMX_USB_COMPLETE_ERROR);
+               }
+       }
+       return 0;
+}
+
+static void octeon_usb_port_callback(struct cvmx_usb_state *usb)
+{
+       struct octeon_hcd *priv = cvmx_usb_to_octeon(usb);
+
+       spin_unlock(&priv->lock);
+       usb_hcd_poll_rh_status(octeon_to_hcd(priv));
+       spin_lock(&priv->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 cvmx_usb_state *usb)
+{
+       union cvmx_usbcx_hfnum usbc_hfnum;
+       union cvmx_usbcx_gintsts usbc_gintsts;
+
+       CVMX_PREFETCH(usb, 0);
+       CVMX_PREFETCH(usb, 1*128);
+       CVMX_PREFETCH(usb, 2*128);
+       CVMX_PREFETCH(usb, 3*128);
+       CVMX_PREFETCH(usb, 4*128);
+
+       /* 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 *priv = hcd_to_octeon(hcd);
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       cvmx_usb_poll(&priv->usb);
+       spin_unlock_irqrestore(&priv->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 *priv = hcd_to_octeon(hcd);
+
+       return cvmx_usb_get_frame_number(&priv->usb);
 }
 
 static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
@@ -206,8 +3006,8 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
 {
        struct octeon_hcd *priv = hcd_to_octeon(hcd);
        struct device *dev = hcd->self.controller;
-       int submit_handle = -1;
-       int pipe_handle;
+       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;
@@ -276,26 +3076,24 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
                                dev = dev->parent;
                        }
                }
-               pipe_handle = cvmx_usb_open_pipe(&priv->usb,
-                                                0,
-                                                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_handle < 0) {
+               pipe = cvmx_usb_open_pipe(&priv->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) {
                        spin_unlock_irqrestore(&priv->lock, flags);
                        dev_dbg(dev, "Failed to create pipe\n");
                        return -ENOMEM;
                }
-               ep->hcpriv = (void *)(0x10000L + pipe_handle);
+               ep->hcpriv = pipe;
        } else {
-               pipe_handle = 0xffff & (long)ep->hcpriv;
+               pipe = ep->hcpriv;
        }
 
        switch (usb_pipetype(urb->pipe)) {
@@ -323,20 +3121,13 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
                         * this saves us a bunch of logic.
                         */
                        urb->setup_packet = (char *)iso_packet;
-                       submit_handle = cvmx_usb_submit_isochronous(&priv->usb, pipe_handle,
-                                                       urb->start_frame,
-                                                       0 /* flags */ ,
-                                                       urb->number_of_packets,
-                                                       iso_packet,
-                                                       urb->transfer_dma,
-                                                       urb->transfer_buffer_length,
-                                                       octeon_usb_urb_complete_callback,
-                                                       urb);
+                       transaction = cvmx_usb_submit_isochronous(&priv->usb,
+                                                                 pipe, urb);
                        /*
                         * If submit failed we need to free our private packet
                         * list.
                         */
-                       if (submit_handle < 0) {
+                       if (!transaction) {
                                urb->setup_packet = NULL;
                                kfree(iso_packet);
                        }
@@ -345,59 +3136,41 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
        case PIPE_INTERRUPT:
                dev_dbg(dev, "Submit interrupt to %d.%d\n",
                        usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
-               submit_handle = cvmx_usb_submit_interrupt(&priv->usb, pipe_handle,
-                                             urb->transfer_dma,
-                                             urb->transfer_buffer_length,
-                                             octeon_usb_urb_complete_callback,
-                                             urb);
+               transaction = cvmx_usb_submit_interrupt(&priv->usb, pipe, urb);
                break;
        case PIPE_CONTROL:
                dev_dbg(dev, "Submit control to %d.%d\n",
                        usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
-               submit_handle = cvmx_usb_submit_control(&priv->usb, pipe_handle,
-                                           urb->setup_dma,
-                                           urb->transfer_dma,
-                                           urb->transfer_buffer_length,
-                                           octeon_usb_urb_complete_callback,
-                                           urb);
+               transaction = cvmx_usb_submit_control(&priv->usb, pipe, urb);
                break;
        case PIPE_BULK:
                dev_dbg(dev, "Submit bulk to %d.%d\n",
                        usb_pipedevice(urb->pipe), usb_pipeendpoint(urb->pipe));
-               submit_handle = cvmx_usb_submit_bulk(&priv->usb, pipe_handle,
-                                        urb->transfer_dma,
-                                        urb->transfer_buffer_length,
-                                        octeon_usb_urb_complete_callback,
-                                        urb);
+               transaction = cvmx_usb_submit_bulk(&priv->usb, pipe, urb);
                break;
        }
-       if (submit_handle < 0) {
+       if (!transaction) {
                spin_unlock_irqrestore(&priv->lock, flags);
                dev_dbg(dev, "Failed to submit\n");
                return -ENOMEM;
        }
-       urb->hcpriv = (void *)(long)(((submit_handle & 0xffff) << 16) | pipe_handle);
+       urb->hcpriv = transaction;
        spin_unlock_irqrestore(&priv->lock, flags);
        return 0;
 }
 
 static void octeon_usb_urb_dequeue_work(unsigned long arg)
 {
+       struct urb *urb;
+       struct urb *next;
        unsigned long flags;
        struct octeon_hcd *priv = (struct octeon_hcd *)arg;
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       while (!list_empty(&priv->dequeue_list)) {
-               int pipe_handle;
-               int submit_handle;
-               struct urb *urb = container_of(priv->dequeue_list.next, struct urb, urb_list);
-               list_del(&urb->urb_list);
-               /* not enqueued on dequeue_list */
-               INIT_LIST_HEAD(&urb->urb_list);
-               pipe_handle = 0xffff & (long)urb->hcpriv;
-               submit_handle = ((long)urb->hcpriv) >> 16;
-               cvmx_usb_cancel(&priv->usb, pipe_handle, submit_handle);
+       list_for_each_entry_safe(urb, next, &priv->dequeue_list, urb_list) {
+               list_del_init(&urb->urb_list);
+               cvmx_usb_cancel(&priv->usb, urb->ep->hcpriv, urb->hcpriv);
        }
 
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -429,12 +3202,12 @@ static void octeon_usb_endpoint_disable(struct usb_hcd *hcd, struct usb_host_end
 
        if (ep->hcpriv) {
                struct octeon_hcd *priv = hcd_to_octeon(hcd);
-               int pipe_handle = 0xffff & (long)ep->hcpriv;
+               struct cvmx_usb_pipe *pipe = ep->hcpriv;
                unsigned long flags;
                spin_lock_irqsave(&priv->lock, flags);
-               cvmx_usb_cancel_all(&priv->usb, pipe_handle);
-               if (cvmx_usb_close_pipe(&priv->usb, pipe_handle))
-                       dev_dbg(dev, "Closing pipe %d failed\n", pipe_handle);
+               cvmx_usb_cancel_all(&priv->usb, pipe);
+               if (cvmx_usb_close_pipe(&priv->usb, pipe))
+                       dev_dbg(dev, "Closing pipe %p failed\n", pipe);
                spin_unlock_irqrestore(&priv->lock, flags);
                ep->hcpriv = NULL;
        }
@@ -506,7 +3279,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                        dev_dbg(dev, " C_CONNECTION\n");
                        /* Clears drivers internal connect status change flag */
                        spin_lock_irqsave(&priv->lock, flags);
-                       cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
+                       priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        break;
                case USB_PORT_FEAT_C_RESET:
@@ -515,7 +3288,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                         * Clears the driver's internal Port Reset Change flag.
                         */
                        spin_lock_irqsave(&priv->lock, flags);
-                       cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
+                       priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        break;
                case USB_PORT_FEAT_C_ENABLE:
@@ -525,7 +3298,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                         * Change flag.
                         */
                        spin_lock_irqsave(&priv->lock, flags);
-                       cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
+                       priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        break;
                case USB_PORT_FEAT_C_SUSPEND:
@@ -540,7 +3313,7 @@ static int octeon_usb_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                        dev_dbg(dev, " C_OVER_CURRENT\n");
                        /* Clears the driver's overcurrent Change flag */
                        spin_lock_irqsave(&priv->lock, flags);
-                       cvmx_usb_set_status(&priv->usb, cvmx_usb_get_status(&priv->usb));
+                       priv->usb.port_status = cvmx_usb_get_status(&priv->usb);
                        spin_unlock_irqrestore(&priv->lock, flags);
                        break;
                default:
@@ -705,7 +3478,7 @@ static int octeon_usb_driver_probe(struct device *dev)
        tasklet_init(&priv->dequeue_tasklet, octeon_usb_urb_dequeue_work, (unsigned long)priv);
        INIT_LIST_HEAD(&priv->dequeue_list);
 
-       status = cvmx_usb_initialize(&priv->usb, usb_num, CVMX_USB_INITIALIZE_FLAGS_CLOCK_AUTO);
+       status = cvmx_usb_initialize(&priv->usb, usb_num);
        if (status) {
                dev_dbg(dev, "USB initialization failed with %d\n", status);
                kfree(hcd);
similarity index 83%
rename from drivers/staging/octeon-usb/cvmx-usbcx-defs.h
rename to drivers/staging/octeon-usb/octeon-hcd.h
index d349d77bc3596f2a8dfd957023288c601683a34a..42fe4fec7d5d842e697283d86a97289a63513605 100644 (file)
@@ -1,7 +1,14 @@
-/***********************license start***************
- * Copyright (c) 2003-2010  Cavium Networks (support@cavium.com). All rights
- * reserved.
+/*
+ * 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
  *     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
+ * 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
  * 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
+ * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
  * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- ***********************license end**************************************/
-
-
-/**
- * cvmx-usbcx-defs.h
- *
- * Configuration and status register (CSR) type definitions for
- * Octeon usbcx.
- *
  */
-#ifndef __CVMX_USBCX_TYPEDEFS_H__
-#define __CVMX_USBCX_TYPEDEFS_H__
+
+#ifndef __OCTEON_HCD_H__
+#define __OCTEON_HCD_H__
 
 #define CVMX_USBCXBASE 0x00016F0010000000ull
 #define CVMX_USBCXREG1(reg, 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
  *
@@ -1525,4 +1537,283 @@ union cvmx_usbcx_hptxsts {
        } s;
 };
 
-#endif
+/**
+ * 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 {
+       uint64_t 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 {
+               uint64_t reserved_20_63 : 44;
+               uint64_t divide2        : 2;
+               uint64_t hclk_rst       : 1;
+               uint64_t p_x_on         : 1;
+               uint64_t p_rtype        : 2;
+               uint64_t p_com_on       : 1;
+               uint64_t p_c_sel        : 2;
+               uint64_t cdiv_byp       : 1;
+               uint64_t sd_mode        : 2;
+               uint64_t s_bist         : 1;
+               uint64_t por            : 1;
+               uint64_t enable         : 1;
+               uint64_t prst           : 1;
+               uint64_t hrst           : 1;
+               uint64_t 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 {
+       uint64_t 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 Impedence 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 internaly 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 opeartion.
+        * @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 opeartion.
+        * @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' internaly 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-eanable 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 {
+               uint64_t txrisetune             : 1;
+               uint64_t txvreftune             : 4;
+               uint64_t txfslstune             : 4;
+               uint64_t txhsxvtune             : 2;
+               uint64_t sqrxtune               : 3;
+               uint64_t compdistune            : 3;
+               uint64_t otgtune                : 3;
+               uint64_t otgdisable             : 1;
+               uint64_t portreset              : 1;
+               uint64_t drvvbus                : 1;
+               uint64_t lsbist                 : 1;
+               uint64_t fsbist                 : 1;
+               uint64_t hsbist                 : 1;
+               uint64_t bist_done              : 1;
+               uint64_t bist_err               : 1;
+               uint64_t tdata_out              : 4;
+               uint64_t siddq                  : 1;
+               uint64_t txpreemphasistune      : 1;
+               uint64_t dma_bmode              : 1;
+               uint64_t usbc_end               : 1;
+               uint64_t usbp_bist              : 1;
+               uint64_t tclk                   : 1;
+               uint64_t dp_pulld               : 1;
+               uint64_t dm_pulld               : 1;
+               uint64_t hst_mode               : 1;
+               uint64_t tuning                 : 4;
+               uint64_t tx_bs_enh              : 1;
+               uint64_t tx_bs_en               : 1;
+               uint64_t loop_enb               : 1;
+               uint64_t vtest_enb              : 1;
+               uint64_t bist_enb               : 1;
+               uint64_t tdata_sel              : 1;
+               uint64_t taddr_in               : 4;
+               uint64_t tdata_in               : 8;
+               uint64_t ate_reset              : 1;
+       } s;
+};
+
+#endif /* __OCTEON_HCD_H__ */
index e14a1bb0436129da4c7f969c4f477063d78da1d9..0315f60497b7fcacc48ca876bb862febed85c759 100644 (file)
@@ -72,7 +72,7 @@ struct cvm_oct_core_state {
        int baseline_cores;
        /*
         * The number of additional cores that could be processing
-        * input packtes.
+        * input packets.
         */
        atomic_t available_cores;
        cpumask_t cpu_state;
@@ -80,6 +80,8 @@ struct cvm_oct_core_state {
 
 static struct cvm_oct_core_state core_state __cacheline_aligned_in_smp;
 
+static int cvm_irq_cpu;
+
 static void cvm_oct_enable_napi(void *_)
 {
        int cpu = smp_processor_id();
@@ -112,11 +114,7 @@ static void cvm_oct_no_more_work(void)
 {
        int cpu = smp_processor_id();
 
-       /*
-        * CPU zero is special.  It always has the irq enabled when
-        * waiting for incoming packets.
-        */
-       if (cpu == 0) {
+       if (cpu == cvm_irq_cpu) {
                enable_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group);
                return;
        }
@@ -135,6 +133,7 @@ static irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id)
 {
        /* Disable the IRQ and start napi_poll. */
        disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);
+       cvm_irq_cpu = smp_processor_id();
        cvm_oct_enable_napi(NULL);
 
        return IRQ_HANDLED;
@@ -514,7 +513,7 @@ void cvm_oct_rx_initialize(void)
        if (NULL == dev_for_napi)
                panic("No net_devices were allocated.");
 
-       if (max_rx_cpus > 1  && max_rx_cpus < num_online_cpus())
+       if (max_rx_cpus >= 1 && max_rx_cpus < num_online_cpus())
                atomic_set(&core_state.available_cores, max_rx_cpus);
        else
                atomic_set(&core_state.available_cores, num_online_cpus());
@@ -526,7 +525,7 @@ void cvm_oct_rx_initialize(void)
                               cvm_oct_napi_poll, rx_napi_weight);
                napi_enable(&cvm_oct_napi[i].napi);
        }
-       /* Register an IRQ hander for to receive POW interrupts */
+       /* Register an IRQ handler to receive POW interrupts */
        i = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group,
                        cvm_oct_do_interrupt, 0, "Ethernet", cvm_oct_device);
 
index af8d62818f13b56e05ada09aedd9f64c4d1da1f0..5108bc0bb573e007bfdcc4981133dab733fed9b6 100644 (file)
@@ -64,31 +64,23 @@ static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
                        if (spx_int_reg.s.spf)
                                pr_err("SPI1: SRX Spi4 interface down\n");
                        if (spx_int_reg.s.calerr)
-                               pr_err("SPI1: SRX Spi4 Calendar table "
-                                      "parity error\n");
+                               pr_err("SPI1: SRX Spi4 Calendar table parity error\n");
                        if (spx_int_reg.s.syncerr)
-                               pr_err("SPI1: SRX Consecutive Spi4 DIP4 "
-                                      "errors have exceeded "
-                                      "SPX_ERR_CTL[ERRCNT]\n");
+                               pr_err("SPI1: SRX Consecutive Spi4 DIP4 errors have exceeded SPX_ERR_CTL[ERRCNT]\n");
                        if (spx_int_reg.s.diperr)
                                pr_err("SPI1: SRX Spi4 DIP4 error\n");
                        if (spx_int_reg.s.tpaovr)
-                               pr_err("SPI1: SRX Selected port has hit "
-                                      "TPA overflow\n");
+                               pr_err("SPI1: SRX Selected port has hit TPA overflow\n");
                        if (spx_int_reg.s.rsverr)
-                               pr_err("SPI1: SRX Spi4 reserved control "
-                                      "word detected\n");
+                               pr_err("SPI1: SRX Spi4 reserved control word detected\n");
                        if (spx_int_reg.s.drwnng)
-                               pr_err("SPI1: SRX Spi4 receive FIFO "
-                                      "drowning/overflow\n");
+                               pr_err("SPI1: SRX Spi4 receive FIFO drowning/overflow\n");
                        if (spx_int_reg.s.clserr)
-                               pr_err("SPI1: SRX Spi4 packet closed on "
-                                      "non-16B alignment without EOP\n");
+                               pr_err("SPI1: SRX Spi4 packet closed on non-16B alignment without EOP\n");
                        if (spx_int_reg.s.spiovr)
                                pr_err("SPI1: SRX Spi4 async FIFO overflow\n");
                        if (spx_int_reg.s.abnorm)
-                               pr_err("SPI1: SRX Abnormal packet "
-                                      "termination (ERR bit)\n");
+                               pr_err("SPI1: SRX Abnormal packet termination (ERR bit)\n");
                        if (spx_int_reg.s.prtnxa)
                                pr_err("SPI1: SRX Port out of range\n");
                }
@@ -99,31 +91,23 @@ static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
 
                        stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(1));
                        if (stx_int_reg.s.syncerr)
-                               pr_err("SPI1: STX Interface encountered a "
-                                      "fatal error\n");
+                               pr_err("SPI1: STX Interface encountered a fatal error\n");
                        if (stx_int_reg.s.frmerr)
-                               pr_err("SPI1: STX FRMCNT has exceeded "
-                                      "STX_DIP_CNT[MAXFRM]\n");
+                               pr_err("SPI1: STX FRMCNT has exceeded STX_DIP_CNT[MAXFRM]\n");
                        if (stx_int_reg.s.unxfrm)
-                               pr_err("SPI1: STX Unexpected framing "
-                                      "sequence\n");
+                               pr_err("SPI1: STX Unexpected framing sequence\n");
                        if (stx_int_reg.s.nosync)
-                               pr_err("SPI1: STX ERRCNT has exceeded "
-                                      "STX_DIP_CNT[MAXDIP]\n");
+                               pr_err("SPI1: STX ERRCNT has exceeded STX_DIP_CNT[MAXDIP]\n");
                        if (stx_int_reg.s.diperr)
-                               pr_err("SPI1: STX DIP2 error on the Spi4 "
-                                      "Status channel\n");
+                               pr_err("SPI1: STX DIP2 error on the Spi4 Status channel\n");
                        if (stx_int_reg.s.datovr)
                                pr_err("SPI1: STX Spi4 FIFO overflow error\n");
                        if (stx_int_reg.s.ovrbst)
-                               pr_err("SPI1: STX Transmit packet burst "
-                                      "too big\n");
+                               pr_err("SPI1: STX Transmit packet burst too big\n");
                        if (stx_int_reg.s.calpar1)
-                               pr_err("SPI1: STX Calendar Table Parity "
-                                      "Error Bank1\n");
+                               pr_err("SPI1: STX Calendar Table Parity Error Bank1\n");
                        if (stx_int_reg.s.calpar0)
-                               pr_err("SPI1: STX Calendar Table Parity "
-                                      "Error Bank0\n");
+                               pr_err("SPI1: STX Calendar Table Parity Error Bank0\n");
                }
 
                cvmx_write_csr(CVMX_SPXX_INT_MSK(1), 0);
@@ -144,31 +128,23 @@ static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
                        if (spx_int_reg.s.spf)
                                pr_err("SPI0: SRX Spi4 interface down\n");
                        if (spx_int_reg.s.calerr)
-                               pr_err("SPI0: SRX Spi4 Calendar table "
-                                      "parity error\n");
+                               pr_err("SPI0: SRX Spi4 Calendar table parity error\n");
                        if (spx_int_reg.s.syncerr)
-                               pr_err("SPI0: SRX Consecutive Spi4 DIP4 "
-                                      "errors have exceeded "
-                                      "SPX_ERR_CTL[ERRCNT]\n");
+                               pr_err("SPI0: SRX Consecutive Spi4 DIP4 errors have exceeded SPX_ERR_CTL[ERRCNT]\n");
                        if (spx_int_reg.s.diperr)
                                pr_err("SPI0: SRX Spi4 DIP4 error\n");
                        if (spx_int_reg.s.tpaovr)
-                               pr_err("SPI0: SRX Selected port has hit "
-                                      "TPA overflow\n");
+                               pr_err("SPI0: SRX Selected port has hit TPA overflow\n");
                        if (spx_int_reg.s.rsverr)
-                               pr_err("SPI0: SRX Spi4 reserved control "
-                                      "word detected\n");
+                               pr_err("SPI0: SRX Spi4 reserved control word detected\n");
                        if (spx_int_reg.s.drwnng)
-                               pr_err("SPI0: SRX Spi4 receive FIFO "
-                                      "drowning/overflow\n");
+                               pr_err("SPI0: SRX Spi4 receive FIFO drowning/overflow\n");
                        if (spx_int_reg.s.clserr)
-                               pr_err("SPI0: SRX Spi4 packet closed on "
-                                      "non-16B alignment without EOP\n");
+                               pr_err("SPI0: SRX Spi4 packet closed on non-16B alignment without EOP\n");
                        if (spx_int_reg.s.spiovr)
                                pr_err("SPI0: SRX Spi4 async FIFO overflow\n");
                        if (spx_int_reg.s.abnorm)
-                               pr_err("SPI0: SRX Abnormal packet "
-                                      "termination (ERR bit)\n");
+                               pr_err("SPI0: SRX Abnormal packet termination (ERR bit)\n");
                        if (spx_int_reg.s.prtnxa)
                                pr_err("SPI0: SRX Port out of range\n");
                }
@@ -179,31 +155,23 @@ static irqreturn_t cvm_oct_spi_rml_interrupt(int cpl, void *dev_id)
 
                        stx_int_reg.u64 &= cvmx_read_csr(CVMX_STXX_INT_MSK(0));
                        if (stx_int_reg.s.syncerr)
-                               pr_err("SPI0: STX Interface encountered a "
-                                      "fatal error\n");
+                               pr_err("SPI0: STX Interface encountered a fatal error\n");
                        if (stx_int_reg.s.frmerr)
-                               pr_err("SPI0: STX FRMCNT has exceeded "
-                                      "STX_DIP_CNT[MAXFRM]\n");
+                               pr_err("SPI0: STX FRMCNT has exceeded STX_DIP_CNT[MAXFRM]\n");
                        if (stx_int_reg.s.unxfrm)
-                               pr_err("SPI0: STX Unexpected framing "
-                                      "sequence\n");
+                               pr_err("SPI0: STX Unexpected framing sequence\n");
                        if (stx_int_reg.s.nosync)
-                               pr_err("SPI0: STX ERRCNT has exceeded "
-                                      "STX_DIP_CNT[MAXDIP]\n");
+                               pr_err("SPI0: STX ERRCNT has exceeded STX_DIP_CNT[MAXDIP]\n");
                        if (stx_int_reg.s.diperr)
-                               pr_err("SPI0: STX DIP2 error on the Spi4 "
-                                      "Status channel\n");
+                               pr_err("SPI0: STX DIP2 error on the Spi4 Status channel\n");
                        if (stx_int_reg.s.datovr)
                                pr_err("SPI0: STX Spi4 FIFO overflow error\n");
                        if (stx_int_reg.s.ovrbst)
-                               pr_err("SPI0: STX Transmit packet burst "
-                                      "too big\n");
+                               pr_err("SPI0: STX Transmit packet burst too big\n");
                        if (stx_int_reg.s.calpar1)
-                               pr_err("SPI0: STX Calendar Table Parity "
-                                      "Error Bank1\n");
+                               pr_err("SPI0: STX Calendar Table Parity Error Bank1\n");
                        if (stx_int_reg.s.calpar0)
-                               pr_err("SPI0: STX Calendar Table Parity "
-                                      "Error Bank0\n");
+                               pr_err("SPI0: STX Calendar Table Parity Error Bank0\n");
                }
 
                cvmx_write_csr(CVMX_SPXX_INT_MSK(0), 0);
index 5631dd9f8201488935799adf5e413611e238d1bd..9b4d0b546b89d8578747470503b0974b2a26b40c 100644 (file)
@@ -78,10 +78,12 @@ static DECLARE_TASKLET(cvm_oct_tx_cleanup_tasklet, cvm_oct_tx_do_cleanup, 0);
 static inline int32_t cvm_oct_adjust_skb_to_free(int32_t skb_to_free, int fau)
 {
        int32_t undo;
-       undo = skb_to_free > 0 ? MAX_SKB_TO_FREE : skb_to_free + MAX_SKB_TO_FREE;
+       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;
+       skb_to_free = -skb_to_free > MAX_SKB_TO_FREE ? MAX_SKB_TO_FREE :
+                                                      -skb_to_free;
        return skb_to_free;
 }
 
@@ -108,8 +110,10 @@ void cvm_oct_free_tx_skbs(struct net_device *dev)
        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);
+               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;
@@ -117,12 +121,14 @@ void cvm_oct_free_tx_skbs(struct net_device *dev)
                        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 = __skb_dequeue(&priv->tx_free_list[qos]);
+                               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);
+                       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;
@@ -211,15 +217,23 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
                if (unlikely(__skb_linearize(skb))) {
                        queue_type = QUEUE_DROP;
                        if (USE_ASYNC_IOBDMA) {
-                               /* Get the number of skbuffs in use by the hardware */
+                               /*
+                                * Get the number of skbuffs in use
+                                * by the hardware
+                                */
                                CVMX_SYNCIOBDMA;
-                               skb_to_free = cvmx_scratch_read64(CVMX_SCR_SCRATCH);
+                               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);
+                               /*
+                                * 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);
+                       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;
                }
@@ -276,7 +290,9 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
                CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64;
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                        struct skb_frag_struct *fs = skb_shinfo(skb)->frags + i;
-                       hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)(page_address(fs->page.p) + fs->page_offset));
+                       hw_buffer.s.addr = XKPHYS_TO_PHYS(
+                               (u64)(page_address(fs->page.p) +
+                               fs->page_offset));
                        hw_buffer.s.size = fs->size;
                        CVM_OCT_SKB_CB(skb)[i + 1] = hw_buffer.u64;
                }
@@ -358,7 +374,9 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        pko_command.s.dontfree = 0;
 
-       hw_buffer.s.back = ((unsigned long)skb->data >> 7) - ((unsigned long)fpa_head >> 7);
+       hw_buffer.s.back = ((unsigned long)skb->data >> 7) -
+                          ((unsigned long)fpa_head >> 7);
+
        *(struct sk_buff **)(fpa_head - sizeof(void *)) = skb;
 
        /*
@@ -422,17 +440,22 @@ dont_put_skbuff_in_hw:
                queue_type = QUEUE_HW;
        }
        if (USE_ASYNC_IOBDMA)
-               cvmx_fau_async_fetch_and_add32(CVMX_SCR_SCRATCH, FAU_TOTAL_TX_TO_CLEAN, 1);
+               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 (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);
+                       spin_unlock_irqrestore(&priv->tx_free_list[qos].lock,
+                                              flags);
                        netif_stop_queue(dev);
-                       spin_lock_irqsave(&priv->tx_free_list[qos].lock, flags);
+                       spin_lock_irqsave(&priv->tx_free_list[qos].lock,
+                                         flags);
                } else {
                        /* If not using normal queueing.  */
                        queue_type = QUEUE_DROP;
@@ -448,7 +471,8 @@ dont_put_skbuff_in_hw:
                                                 priv->queue + qos,
                                                 pko_command, hw_buffer,
                                                 CVMX_PKO_LOCK_NONE))) {
-               printk_ratelimited("%s: Failed to send the packet\n", dev->name);
+               printk_ratelimited("%s: Failed to send the packet\n",
+                                  dev->name);
                queue_type = QUEUE_DROP;
        }
 skip_xmit:
@@ -493,7 +517,8 @@ skip_xmit:
                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);
+               total_to_clean = cvmx_fau_fetch_and_add32(
+                                               FAU_TOTAL_TX_TO_CLEAN, 1);
        }
 
        if (total_to_clean & 0x3ff) {
@@ -527,8 +552,8 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev)
        /* Get a work queue entry */
        cvmx_wqe_t *work = cvmx_fpa_alloc(CVMX_FPA_WQE_POOL);
        if (unlikely(work == NULL)) {
-               printk_ratelimited("%s: Failed to allocate a work "
-                                  "queue entry\n", dev->name);
+               printk_ratelimited("%s: Failed to allocate a work queue entry\n",
+                                  dev->name);
                priv->stats.tx_dropped++;
                dev_kfree_skb(skb);
                return 0;
@@ -709,7 +734,7 @@ void cvm_oct_tx_initialize(void)
 
        /* Disable the interrupt.  */
        cvmx_write_csr(CVMX_CIU_TIMX(1), 0);
-       /* Register an IRQ hander for to receive CIU_TIMX(1) interrupts */
+       /* 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);
index c3a90e7012afaddbfa5c0959d35d088de15ab562..8aba66e4a3e412639415f9f77e6ea13a52a38a44 100644 (file)
@@ -163,11 +163,13 @@ static void cvm_oct_periodic_worker(struct work_struct *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]);
+       cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats(
+                                               cvm_oct_device[priv->port]);
 
        if (!atomic_read(&cvm_oct_poll_queue_stopping))
-               queue_delayed_work(cvm_oct_poll_queue, &priv->port_periodic_work, HZ);
- }
+               queue_delayed_work(cvm_oct_poll_queue,
+                                               &priv->port_periodic_work, HZ);
+}
 
 static void cvm_oct_configure_common_hw(void)
 {
@@ -584,8 +586,8 @@ static const struct net_device_ops cvm_oct_pow_netdev_ops = {
 
 extern void octeon_mdiobus_force_mod_depencency(void);
 
-static struct device_node *cvm_oct_of_get_child(const struct device_node *parent,
-                                                          int reg_val)
+static struct device_node *cvm_oct_of_get_child(
+                               const struct device_node *parent, int reg_val)
 {
        struct device_node *node = NULL;
        int size;
@@ -603,7 +605,7 @@ static struct device_node *cvm_oct_of_get_child(const struct device_node *parent
 }
 
 static struct device_node *cvm_oct_node_for_port(struct device_node *pip,
-                                                           int interface, int port)
+                                                       int interface, int port)
 {
        struct device_node *ni, *np;
 
@@ -713,7 +715,8 @@ static int cvm_oct_probe(struct platform_device *pdev)
                int port;
                int port_index;
 
-               for (port_index = 0, port = cvmx_helper_get_ipd_port(interface, 0);
+               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;
@@ -726,7 +729,8 @@ static int cvm_oct_probe(struct platform_device *pdev)
 
                        /* Initialize the device private structure. */
                        priv = netdev_priv(dev);
-                       priv->of_node = cvm_oct_node_for_port(pip, interface, port_index);
+                       priv->of_node = cvm_oct_node_for_port(pip, interface,
+                                                               port_index);
 
                        INIT_DELAYED_WORK(&priv->port_periodic_work,
                                          cvm_oct_periodic_worker);
@@ -793,7 +797,7 @@ static int cvm_oct_probe(struct platform_device *pdev)
                                    cvmx_pko_get_num_queues(priv->port) *
                                    sizeof(uint32_t);
                                queue_delayed_work(cvm_oct_poll_queue,
-                                                  &priv->port_periodic_work, HZ);
+                                               &priv->port_periodic_work, HZ);
                        }
                }
        }
index 2ff015d8450991ded2ba4c49ba80d80a286e64a5..d277f048789e615afda6c4db4bbcb81d1f64923c 100644 (file)
@@ -1,7 +1,8 @@
 config FB_OLPC_DCON
        tristate "One Laptop Per Child Display CONtroller support"
        depends on OLPC && FB
-       select I2C
+       depends on I2C
+       depends on (GPIO_CS5535 || GPIO_CS5535=n)
        select BACKLIGHT_CLASS_DEVICE
        ---help---
          In order to support very low power operation, the XO laptop uses a
index 198595e8d742f798256198d57946ca18012295a5..92b02891704d04738365011cd28f6f93b7055dd8 100644 (file)
@@ -383,7 +383,7 @@ static void dcon_set_source(struct dcon_priv *dcon, int arg)
 
        dcon->pending_src = arg;
 
-       if ((dcon->curr_src != arg) && !work_pending(&dcon->switch_source))
+       if (dcon->curr_src != arg)
                schedule_work(&dcon->switch_source);
 }
 
index 4247d60c91861929fd17da303eba9653d3bd993d..9f6ebdb23740596f530e9ab5d52194ca3c9c438e 100644 (file)
@@ -390,10 +390,6 @@ static int __init quickstart_init(void)
 {
        int ret;
 
-       /* ACPI Check */
-       if (acpi_disabled)
-               return -ENODEV;
-
        /* ACPI driver register */
        ret = acpi_bus_register_driver(&quickstart_acpi_driver);
        if (ret)
index 10b22100dd3a223d702487838450850197446329..304579096562aa0011f0159e0b26665aeb4815ea 100644 (file)
@@ -858,7 +858,7 @@ static inline void ieee80211_extract_country_ie(
 
 }
 
-int
+static int
 ieee80211_TranslateToDbm(
        unsigned char SignalStrengthIndex       // 0-100 index.
        )
index b65db542e1ab5025e2185bebb957f43e7eaac8b6..04058263398e600bb1d416393f4989566b3bb46d 100644 (file)
@@ -887,7 +887,8 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
        return skb;
 }
 
-struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
+static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
+                                           u8 *dest)
 {
        struct sk_buff *skb;
        u8* tag;
@@ -940,7 +941,8 @@ struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
        return skb;
 }
 
-struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
+static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
+                                          int status, u8 *dest)
 {
        struct sk_buff *skb;
        struct ieee80211_authentication *auth;
index b3466530cf9429a44dba589f3322ba4c2a6a1ca3..d9601839adac63f1d36c1ede35c7e56511c473ea 100644 (file)
@@ -239,8 +239,8 @@ void ieee80211_txb_free(struct ieee80211_txb *txb) {
        kfree(txb);
 }
 
-struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
-                                         int gfp_mask)
+static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
+                                                gfp_t gfp_mask)
 {
        struct ieee80211_txb *txb;
        int i;
index 5947a6f8e16f971a46ef3d89b363ebae1ed3450e..55dfd5e450cd1d2c370716ba8e3c88c432fcdae3 100644 (file)
@@ -160,34 +160,34 @@ static struct pci_driver rtl8180_pci_driver = {
 
 u8 read_nic_byte(struct net_device *dev, int x)
 {
-       return 0xff&readb((u8 *)dev->mem_start + x);
+       return 0xff&readb((u8 __iomem *)dev->mem_start + x);
 }
 
 u32 read_nic_dword(struct net_device *dev, int x)
 {
-       return readl((u8 *)dev->mem_start + x);
+       return readl((u8 __iomem *)dev->mem_start + x);
 }
 
 u16 read_nic_word(struct net_device *dev, int x)
 {
-       return readw((u8 *)dev->mem_start + x);
+       return readw((u8 __iomem *)dev->mem_start + x);
 }
 
 void write_nic_byte(struct net_device *dev, int x, u8 y)
 {
-       writeb(y, (u8 *)dev->mem_start + x);
+       writeb(y, (u8 __iomem *)dev->mem_start + x);
        udelay(20);
 }
 
 void write_nic_dword(struct net_device *dev, int x, u32 y)
 {
-       writel(y, (u8 *)dev->mem_start + x);
+       writel(y, (u8 __iomem *)dev->mem_start + x);
        udelay(20);
 }
 
 void write_nic_word(struct net_device *dev, int x, u16 y)
 {
-       writew(y, (u8 *)dev->mem_start + x);
+       writew(y, (u8 __iomem *)dev->mem_start + x);
        udelay(20);
 }
 
@@ -275,18 +275,18 @@ static int proc_get_stats_tx(struct seq_file *m, void *v)
        return 0;
 }
 
-void rtl8180_proc_module_init(void)
+static void rtl8180_proc_module_init(void)
 {
        DMESG("Initializing proc filesystem");
        rtl8180_proc = proc_mkdir(RTL8180_MODULE_NAME, init_net.proc_net);
 }
 
-void rtl8180_proc_module_remove(void)
+static void rtl8180_proc_module_remove(void)
 {
        remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net);
 }
 
-void rtl8180_proc_remove_one(struct net_device *dev)
+static void rtl8180_proc_remove_one(struct net_device *dev)
 {
        remove_proc_subtree(dev->name, rtl8180_proc);
 }
@@ -325,7 +325,7 @@ static const struct rtl8180_proc_file rtl8180_proc_files[] = {
        { "" }
 };
 
-void rtl8180_proc_init_one(struct net_device *dev)
+static void rtl8180_proc_init_one(struct net_device *dev)
 {
        const struct rtl8180_proc_file *f;
        struct proc_dir_entry *dir;
@@ -351,8 +351,8 @@ void rtl8180_proc_init_one(struct net_device *dev)
   data type+functions in kernel
 */
 
-short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
-               struct buffer **bufferhead)
+static short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
+                       struct buffer **bufferhead)
 {
        struct buffer *tmp;
 
@@ -463,7 +463,7 @@ int get_curr_tx_free_desc(struct net_device *dev, int priority)
        return ret;
 }
 
-short check_nic_enought_desc(struct net_device *dev, int priority)
+static short check_nic_enought_desc(struct net_device *dev, int priority)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        struct ieee80211_device *ieee = netdev_priv(dev);
@@ -589,7 +589,7 @@ void fix_rx_fifo(struct net_device *dev)
        set_nic_rxring(dev);
 }
 
-void rtl8180_irq_disable(struct net_device *dev)
+static void rtl8180_irq_disable(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
@@ -705,8 +705,8 @@ void rtl8180_rtx_disable(struct net_device *dev)
                dev_kfree_skb_any(priv->rx_skb);
 }
 
-short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
-                        int addr)
+static short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
+                               int addr)
 {
        int i;
        u32 *desc;
@@ -830,7 +830,7 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
        return 0;
 }
 
-void free_tx_desc_rings(struct net_device *dev)
+static void free_tx_desc_rings(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct pci_dev *pdev = priv->pdev;
@@ -866,7 +866,7 @@ void free_tx_desc_rings(struct net_device *dev)
        buffer_free(dev, &(priv->txbeaconbufs), priv->txbuffsize, 1);
 }
 
-void free_rx_desc_ring(struct net_device *dev)
+static void free_rx_desc_ring(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct pci_dev *pdev = priv->pdev;
@@ -878,7 +878,7 @@ void free_rx_desc_ring(struct net_device *dev)
        buffer_free(dev, &(priv->rxbuffer), priv->rxbuffersize, 0);
 }
 
-short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
+static short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
 {
        int i;
        u32 *desc;
@@ -1092,7 +1092,7 @@ u16 N_DBPSOfRate(u16 DataRate)
 /*
  * For Netgear case, they want good-looking signal strength.
  */
-long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
+static long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
 {
        long RetSS;
 
@@ -1128,7 +1128,7 @@ long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
 /*
  * Translate 0-100 signal strength index into dBm.
  */
-long TranslateToDbm8185(u8 SignalStrengthIndex)
+static long TranslateToDbm8185(u8 SignalStrengthIndex)
 {
        long SignalPower;
 
@@ -1145,8 +1145,8 @@ long TranslateToDbm8185(u8 SignalStrengthIndex)
  * No dramatic adjustion is apply because dynamic mechanism need some degree
  * of correctness. Ported from 8187B.
  */
-void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
-                                          bool bCckRate)
+static void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
+                                                 bool bCckRate)
 {
        /* Determin the current packet is CCK rate. */
        priv->bCurCCKPkt = bCckRate;
@@ -1170,7 +1170,7 @@ void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
 /*
  * This is rough RX isr handling routine
  */
-void rtl8180_rx(struct net_device *dev)
+static void rtl8180_rx(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct sk_buff *tmp_skb;
@@ -1496,7 +1496,7 @@ drop: /* this is used when we have not enough mem */
 }
 
 
-void rtl8180_dma_kick(struct net_device *dev, int priority)
+static void rtl8180_dma_kick(struct net_device *dev, int priority)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
@@ -1508,7 +1508,7 @@ void rtl8180_dma_kick(struct net_device *dev, int priority)
        force_pci_posting(dev);
 }
 
-void rtl8180_data_hard_stop(struct net_device *dev)
+static void rtl8180_data_hard_stop(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
@@ -1518,7 +1518,7 @@ void rtl8180_data_hard_stop(struct net_device *dev)
        rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
 }
 
-void rtl8180_data_hard_resume(struct net_device *dev)
+static void rtl8180_data_hard_resume(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
@@ -1532,8 +1532,9 @@ void rtl8180_data_hard_resume(struct net_device *dev)
  * This function TX data frames when the ieee80211 stack requires this.
  * It checks also if we need to stop the ieee tx queue, eventually do it
  */
-void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int
-rate) {
+static void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
+                                  int rate)
+{
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        int mode;
        struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *) skb->data;
@@ -1584,7 +1585,7 @@ rate) {
  * might use a different lock than tx_lock (for example mgmt_tx_lock)
  */
 /* these function may loop if invoked with 0 descriptors or 0 len buffer */
-int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        unsigned long flags;
@@ -1660,7 +1661,7 @@ u16 rtl8180_len2duration(u32 len, short rate, short *ext)
        return duration;
 }
 
-void rtl8180_prepare_beacon(struct net_device *dev)
+static void rtl8180_prepare_beacon(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct sk_buff *skb;
@@ -1704,7 +1705,7 @@ short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority,
        u16                     RtsDur = 0;
        u16                     ThisFrameTime = 0;
        u16                     TxDescDuration = 0;
-       u8                      ownbit_flag = false;
+       bool                    ownbit_flag = false;
 
        switch (priority) {
        case MANAGE_PRIORITY:
@@ -1953,7 +1954,7 @@ short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority,
 
 void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
 
-void rtl8180_link_change(struct net_device *dev)
+static void rtl8180_link_change(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u16 beacon_interval;
@@ -1976,7 +1977,7 @@ void rtl8180_link_change(struct net_device *dev)
        rtl8180_set_chan(dev, priv->chan);
 }
 
-void rtl8180_rq_tx_ack(struct net_device *dev)
+static void rtl8180_rq_tx_ack(struct net_device *dev)
 {
 
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -1985,7 +1986,7 @@ void rtl8180_rq_tx_ack(struct net_device *dev)
        priv->ack_tx_to_ieee = 1;
 }
 
-short rtl8180_is_tx_queue_empty(struct net_device *dev)
+static short rtl8180_is_tx_queue_empty(struct net_device *dev)
 {
 
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2023,7 +2024,7 @@ short rtl8180_is_tx_queue_empty(struct net_device *dev)
        return 1;
 }
 
-void rtl8180_hw_wakeup(struct net_device *dev)
+static void rtl8180_hw_wakeup(struct net_device *dev)
 {
        unsigned long flags;
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2035,7 +2036,7 @@ void rtl8180_hw_wakeup(struct net_device *dev)
        spin_unlock_irqrestore(&priv->ps_lock, flags);
 }
 
-void rtl8180_hw_sleep_down(struct net_device *dev)
+static void rtl8180_hw_sleep_down(struct net_device *dev)
 {
        unsigned long flags;
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -2046,7 +2047,7 @@ void rtl8180_hw_sleep_down(struct net_device *dev)
        spin_unlock_irqrestore(&priv->ps_lock, flags);
 }
 
-void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
+static void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u32 rb = jiffies;
@@ -2093,7 +2094,7 @@ void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
        spin_unlock_irqrestore(&priv->ps_lock, flags);
 }
 
-void rtl8180_wmm_param_update(struct work_struct *work)
+static void rtl8180_wmm_param_update(struct work_struct *work)
 {
        struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wmm_param_update_wq);
        struct net_device *dev = ieee->dev;
@@ -2195,7 +2196,7 @@ void rtl8180_hw_sleep_wq(struct work_struct *work);
 void rtl8180_sw_antenna_wq(struct work_struct *work);
 void rtl8180_watch_dog(struct net_device *dev);
 
-void watch_dog_adaptive(unsigned long data)
+static void watch_dog_adaptive(unsigned long data)
 {
        struct r8180_priv *priv = ieee80211_priv((struct net_device *)data);
 
@@ -2757,7 +2758,7 @@ void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
        mdelay(1);
 }
 
-void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
+static void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
 {
        u32 phyw;
 
@@ -2969,7 +2970,7 @@ void rtl8180_watch_dog(struct net_device *dev)
        priv->ieee80211->NumRxBcnInPeriod = 0;
 }
 
-int _rtl8180_up(struct net_device *dev)
+static int _rtl8180_up(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -2991,7 +2992,7 @@ int _rtl8180_up(struct net_device *dev)
        return 0;
 }
 
-int rtl8180_open(struct net_device *dev)
+static int rtl8180_open(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        int ret;
@@ -3012,7 +3013,7 @@ int rtl8180_up(struct net_device *dev)
        return _rtl8180_up(dev);
 }
 
-int rtl8180_close(struct net_device *dev)
+static int rtl8180_close(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        int ret;
@@ -3065,7 +3066,7 @@ void rtl8180_restart_wq(struct work_struct *work)
        up(&priv->wx_sem);
 }
 
-void rtl8180_restart(struct net_device *dev)
+static void rtl8180_restart(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -3106,7 +3107,7 @@ static void r8180_set_multicast(struct net_device *dev)
        priv->promisc = promisc;
 }
 
-int r8180_set_mac_adr(struct net_device *dev, void *mac)
+static int r8180_set_mac_adr(struct net_device *dev, void *mac)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        struct sockaddr *addr = mac;
@@ -3129,7 +3130,7 @@ int r8180_set_mac_adr(struct net_device *dev, void *mac)
 }
 
 /* based on ipw2200 driver */
-int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        struct iwreq *wrq = (struct iwreq *) rq;
@@ -3251,7 +3252,7 @@ static int rtl8180_pci_probe(struct pci_dev *pdev,
        return 0;
 fail1:
        if (dev->mem_start != (unsigned long)NULL) {
-               iounmap((void *)dev->mem_start);
+               iounmap((void __iomem *)dev->mem_start);
                release_mem_region(pci_resource_start(pdev, 1),
                                   pci_resource_len(pdev, 1));
        }
@@ -3268,7 +3269,6 @@ fail_free:
        pci_disable_device(pdev);
 
        DMESG("wlan driver load failed\n");
-       pci_set_drvdata(pdev, NULL);
        return ret;
 }
 
@@ -3298,7 +3298,7 @@ static void rtl8180_pci_remove(struct pci_dev *pdev)
                free_tx_desc_rings(dev);
 
                if (dev->mem_start != (unsigned long)NULL) {
-                       iounmap((void *)dev->mem_start);
+                       iounmap((void __iomem *)dev->mem_start);
                        release_mem_region(pci_resource_start(pdev, 1),
                                           pci_resource_len(pdev, 1));
                }
@@ -3369,7 +3369,7 @@ static void __exit rtl8180_pci_module_exit(void)
        DMESG("Exiting");
 }
 
-void rtl8180_try_wake_queue(struct net_device *dev, int pri)
+static void rtl8180_try_wake_queue(struct net_device *dev, int pri)
 {
        unsigned long flags;
        short enough_desc;
@@ -3383,7 +3383,7 @@ void rtl8180_try_wake_queue(struct net_device *dev, int pri)
                ieee80211_rtl_wake_queue(priv->ieee80211);
 }
 
-void rtl8180_tx_isr(struct net_device *dev, int pri, short error)
+static void rtl8180_tx_isr(struct net_device *dev, int pri, short error)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        u32 *tail; /* tail virtual addr */
index b8f2ba010a04e74af236c7883a546eb11935e792..980bafd12277f29bb8a5f6888a1d8456d1177f47 100644 (file)
@@ -10,10 +10,10 @@ bool CheckHighPower(struct net_device *dev)
        struct r8180_priv *priv = ieee80211_priv(dev);
        struct ieee80211_device *ieee = priv->ieee80211;
 
-       if(!priv->bRegHighPowerMechanism)
+       if (!priv->bRegHighPowerMechanism)
                return false;
 
-       if(ieee->state == IEEE80211_LINKED_SCANNING)
+       if (ieee->state == IEEE80211_LINKED_SCANNING)
                return false;
 
        return true;
@@ -30,7 +30,7 @@ bool CheckHighPower(struct net_device *dev)
  *             and they are related to OFDM and MAC registers.
  *             So, we don't want to update it so frequently in per-Rx packet base.
  */
-void DoTxHighPower(struct net_device *dev)
+static void DoTxHighPower(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u16                     HiPwrUpperTh = 0;
@@ -57,15 +57,15 @@ void DoTxHighPower(struct net_device *dev)
                /* Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah */
 
                priv->bToUpdateTxPwr = true;
-               u1bTmp= read_nic_byte(dev, CCK_TXAGC);
+               u1bTmp = read_nic_byte(dev, CCK_TXAGC);
 
                /* If it never enter High Power. */
                if (CckTxPwrIdx == u1bTmp) {
-                       u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0;  /* 8dbm */
+                       u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0;  /* 8dbm */
                        write_nic_byte(dev, CCK_TXAGC, u1bTmp);
 
-                       u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
-                       u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0;  /* 8dbm */
+                       u1bTmp = read_nic_byte(dev, OFDM_TXAGC);
+                       u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0;  /* 8dbm */
                        write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
                }
 
@@ -74,12 +74,12 @@ void DoTxHighPower(struct net_device *dev)
                if (priv->bToUpdateTxPwr) {
                        priv->bToUpdateTxPwr = false;
                        /* SD3 required. */
-                       u1bTmp= read_nic_byte(dev, CCK_TXAGC);
+                       u1bTmp = read_nic_byte(dev, CCK_TXAGC);
                        if (u1bTmp < CckTxPwrIdx) {
                                write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
                        }
 
-                       u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
+                       u1bTmp = read_nic_byte(dev, OFDM_TXAGC);
                        if (u1bTmp < OfdmTxPwrIdx) {
                                write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
                        }
@@ -97,7 +97,7 @@ void DoTxHighPower(struct net_device *dev)
 void rtl8180_tx_pw_wq(struct work_struct *work)
 {
        struct delayed_work *dwork = to_delayed_work(work);
-       struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
+       struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, tx_pw_wq);
        struct net_device *dev = ieee->dev;
 
        DoTxHighPower(dev);
@@ -125,7 +125,7 @@ bool CheckDig(struct net_device *dev)
 /*
  *     Implementation of DIG for Zebra and Zebra2.
  */
-void DIG_Zebra(struct net_device *dev)
+static void DIG_Zebra(struct net_device *dev)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u16                     CCKFalseAlarm, OFDMFalseAlarm;
@@ -149,11 +149,11 @@ void DIG_Zebra(struct net_device *dev)
 
 #if 1 /* lzm reserved 080826 */
        AwakePeriodIn2Sec = (2000 - priv->DozePeriodInPast2Sec);
-       priv ->DozePeriodInPast2Sec = 0;
+       priv->DozePeriodInPast2Sec = 0;
 
        if (AwakePeriodIn2Sec) {
-               OfdmFA1 = (u16)((OfdmFA1 * AwakePeriodIn2Sec) / 2000) ;
-               OfdmFA2 = (u16)((OfdmFA2 * AwakePeriodIn2Sec) / 2000) ;
+               OfdmFA1 = (u16)((OfdmFA1 * AwakePeriodIn2Sec) / 2000);
+               OfdmFA2 = (u16)((OfdmFA2 * AwakePeriodIn2Sec) / 2000);
        } else {
                ;
        }
@@ -202,7 +202,7 @@ void DIG_Zebra(struct net_device *dev)
 /*
  *     Dispatch DIG implementation according to RF.
  */
-void DynamicInitGain(struct net_device *dev)
+static void DynamicInitGain(struct net_device *dev)
 {
        DIG_Zebra(dev);
 }
@@ -210,7 +210,7 @@ void DynamicInitGain(struct net_device *dev)
 void rtl8180_hw_dig_wq(struct work_struct *work)
 {
        struct delayed_work *dwork = to_delayed_work(work);
-       struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
+       struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, hw_dig_wq);
        struct net_device *dev = ieee->dev;
        struct r8180_priv *priv = ieee80211_priv(dev);
 
@@ -223,7 +223,7 @@ void rtl8180_hw_dig_wq(struct work_struct *work)
 
 }
 
-int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
+static int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
 {
        u8 rate_len;
        u8 rate_ex_len;
@@ -234,7 +234,7 @@ int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
 
        rate_len = priv->ieee80211->current_network.rates_len;
        rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
-       for (idx=0; idx < rate_len; idx++) {
+       for (idx = 0; idx < rate_len; idx++) {
                if ((priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate) {
                        Found = 1;
                        goto found_rate;
@@ -247,7 +247,7 @@ int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
                }
        }
        return Found;
-       found_rate:
+found_rate:
        return Found;
 }
 
@@ -255,7 +255,7 @@ int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
  *     Get the Tx rate one degree up form the input rate in the supported rates.
  *     Return the upgrade rate if it is successed, otherwise return the input rate.
  */
-u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
+static u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u8                      UpRate;
@@ -315,7 +315,7 @@ u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
  *     Return the degrade rate if it is successed, otherwise return the input rate.
  */
 
-u8 GetDegradeTxRate(struct net_device *dev, u8 rate)
+static u8 GetDegradeTxRate(struct net_device *dev, u8 rate)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        u8                      DownRate;
@@ -375,7 +375,7 @@ u8 GetDegradeTxRate(struct net_device *dev, u8 rate)
  *      CCK rate.
  */
 
-bool MgntIsCckRate(u16 rate)
+static bool MgntIsCckRate(u16 rate)
 {
        bool bReturn = false;
 
@@ -397,7 +397,7 @@ void TxPwrTracking87SE(struct net_device *dev)
 
        tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
        CurrentThermal = (tmpu1Byte & 0xf0) >> 4; /*[ 7:4]: thermal meter indication. */
-       CurrentThermal = (CurrentThermal > 0x0c) ? 0x0c:CurrentThermal;/* lzm add 080826 */
+       CurrentThermal = (CurrentThermal > 0x0c) ? 0x0c : CurrentThermal;/* lzm add 080826 */
 
        if (CurrentThermal != priv->ThermalMeter) {
                /* Update Tx Power level on each channel. */
@@ -435,7 +435,7 @@ void TxPwrTracking87SE(struct net_device *dev)
        }
        priv->ThermalMeter = CurrentThermal;
 }
-void StaRateAdaptive87SE(struct net_device *dev)
+static void StaRateAdaptive87SE(struct net_device *dev)
 {
        struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
        unsigned long   CurrTxokCnt;
@@ -513,7 +513,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
         */
 
        /*
-        *  11Mbps or 36Mbps
+        * 11Mbps or 36Mbps
         * Check more times in these rate(key rates).
         */
        if (priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
@@ -542,7 +542,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                }
        } else if (CurrSignalStrength > -47 && (CurrRetryRate < 50)) {
                /*
-                * 2For High Power
+                * 2For High Power
                 *
                 * Return to highest data rate, if signal strength is good enough.
                 * SignalStrength threshold(-50dbm) is for RTL8186.
@@ -577,8 +577,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
 
                if (bTryDown && (CurrSignalStrength < -75)) /* cable link */
                        priv->TryDownCountLowData += TryDownTh;
-       }
-       else if (priv->CurrentOperaRate == 96) {
+       } else if (priv->CurrentOperaRate == 96) {
                /* 2For 48Mbps */
                /* Air Link */
                if (((CurrRetryRate > 48) && (priv->LastRetryRate > 47))) {
@@ -593,7 +592,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        bTryUp = true;
                }
 
-               if (bTryDown && (CurrSignalStrength < -75)){
+               if (bTryDown && (CurrSignalStrength < -75)) {
                        priv->TryDownCountLowData += TryDownTh;
                }
        } else if (priv->CurrentOperaRate == 72) {
@@ -618,7 +617,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        bTryDown = true;
                } else if (((CurrRetryRate > 33) && (priv->LastRetryRate > 32)) && (CurrSignalStrength > -82)) { /* Cable Link */
                        bTryDown = true;
-               } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2 )) {
+               } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
                        bTryDown = true;
                        priv->TryDownCountLowData += TryDownTh;
                } else if ((CurrRetryRate < 20) && (priv->LastRetryRate < 21)) { /* TO DO: need to consider (RSSI) */
@@ -641,8 +640,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                /* 2For 11Mbps */
                if (CurrRetryRate > 95) {
                        bTryDown = true;
-               }
-               else if ((CurrRetryRate < 29) && (priv->LastRetryRate < 30)) { /*TO DO: need to consider (RSSI) */
+               } else if ((CurrRetryRate < 29) && (priv->LastRetryRate < 30)) { /*TO DO: need to consider (RSSI) */
                        bTryUp = true;
                }
        } else if (priv->CurrentOperaRate == 11) {
@@ -672,7 +670,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
        /* 1 Test Upgrading Tx Rate
         * Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
         * To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
-        */ 
+        */
        if (!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
                && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2) {
                if (jiffies % (CurrRetryRate + 101) == 0) {
@@ -702,7 +700,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        if (priv->CurrentOperaRate == 22)
                                bUpdateInitialGain = true;
 
-                       /* 
+                       /*
                         * The difference in throughput between 48Mbps and 36Mbps is 8M.
                         * So, we must be careful in this rate scale. Isaiah 2008-02-15.
                         */
@@ -718,7 +716,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        if (priv->CurrentOperaRate == 36) {
                                priv->bUpdateARFR = true;
                                write_nic_word(dev, ARFR, 0x0F8F); /* bypass 12/9/6 */
-                       } else if(priv->bUpdateARFR) {
+                       } else if (priv->bUpdateARFR) {
                                priv->bUpdateARFR = false;
                                write_nic_word(dev, ARFR, 0x0FFF); /* set 1M ~ 54Mbps. */
                        }
@@ -732,7 +730,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                }
        } else {
                if (priv->TryupingCount > 0)
-                       priv->TryupingCount --;
+                       priv->TryupingCount--;
        }
 
        if (bTryDown) {
@@ -757,7 +755,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
 
                        /* Reduce chariot training time at weak signal strength situation. SD3 ED demand. */
-                       if ((CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 )) {
+                       if ((CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72)) {
                                priv->CurrentOperaRate = 72;
                        }
 
@@ -781,8 +779,8 @@ void StaRateAdaptive87SE(struct net_device *dev)
                        priv->TryDownCountLowData--;
        }
 
-       /* 
-        * Keep the Tx fail rate count to equal to 0x15 at most. 
+       /*
+        * Keep the Tx fail rate count to equal to 0x15 at most.
         * Reduce the fail count at least to 10 sec if tx rate is tending stable.
         */
        if (priv->FailTxRateCount >= 0x15 ||
@@ -803,14 +801,14 @@ void StaRateAdaptive87SE(struct net_device *dev)
                if (u1bCck == CckTxPwrIdx) {
                        if (u1bOfdm != (OfdmTxPwrIdx + 2)) {
                        priv->bEnhanceTxPwr = true;
-                       u1bOfdm = ((u1bOfdm + 2) > 35) ? 35: (u1bOfdm + 2);
+                       u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2);
                        write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
                        }
                } else if (u1bCck < CckTxPwrIdx) {
                /* case 2: enter high power */
                        if (!priv->bEnhanceTxPwr) {
                                priv->bEnhanceTxPwr = true;
-                               u1bOfdm = ((u1bOfdm + 2) > 35) ? 35: (u1bOfdm + 2);
+                               u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2);
                                write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
                        }
                }
@@ -826,7 +824,7 @@ void StaRateAdaptive87SE(struct net_device *dev)
                /* case 2: enter high power */
                else if (u1bCck < CckTxPwrIdx) {
                        priv->bEnhanceTxPwr = false;
-                       u1bOfdm = ((u1bOfdm - 2) > 0) ? (u1bOfdm - 2): 0;
+                       u1bOfdm = ((u1bOfdm - 2) > 0) ? (u1bOfdm - 2) : 0;
                        write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
                }
        }
@@ -851,7 +849,7 @@ SetInitialGain:
                                else
                                        priv->InitialGain--;
 
-                               printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
+                               printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate);
                                UpdateInitialGain(dev);
                        }
                } else { /* OFDM */
@@ -859,7 +857,7 @@ SetInitialGain:
                                priv->InitialGainBackUp = priv->InitialGain;
 
                                priv->InitialGain++;
-                               printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
+                               printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate);
                                UpdateInitialGain(dev);
                        }
                }
@@ -904,7 +902,7 @@ void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength)
        } else { /* Initialization case. */
                priv->AdRxSignalStrength = SignalStrength;
        }
-       
+
        if (priv->LastRxPktAntenna) /* Main antenna. */
                priv->AdMainAntennaRxOkCnt++;
        else     /* Aux antenna. */
@@ -943,7 +941,7 @@ bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex)
                break;
        }
 
-       if(bAntennaSwitched)
+       if (bAntennaSwitched)
                priv->CurrAntennaIndex = u1bAntennaIndex;
 
        return bAntennaSwitched;
@@ -1000,8 +998,8 @@ void SwAntennaDiversity(struct net_device *dev)
                priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
 
                priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
-                                       priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
-               if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) {
+                                       priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;
+               if (priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) {
                /* Rx signal strength is not improved after we swtiched antenna. => Swich back. */
                        /* Increase Antenna Diversity checking period due to bad decision. */
                        priv->AdCheckPeriod *= 2;
@@ -1083,7 +1081,7 @@ void SwAntennaDiversity(struct net_device *dev)
 
                                        priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
                                        priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
-                                                               priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;/* +by amy 080312 */
+                                                               priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;/* +by amy 080312 */
                                }
 
                                /* Reduce Antenna Diversity checking period if possible. */
index 9ae96b7852f30d328330ac180a822be56cf20eb2..7c9a8bfe6d889c2f0ec3e89cc16192bdb2f0d309 100644 (file)
@@ -136,7 +136,7 @@ static const u16 rtl8225z2_rxgain[] = {
 
 };
 
-void rtl8225z2_set_gain(struct net_device *dev, short gain)
+static void rtl8225z2_set_gain(struct net_device *dev, short gain)
 {
        const u8 *rtl8225_gain;
        struct r8180_priv *priv = ieee80211_priv(dev);
@@ -279,8 +279,8 @@ void rtl8225z2_rf_close(struct net_device *dev)
  * Map dBm into Tx power index according to current HW model, for example,
  * RF and PA, and current wireless mode.
  */
-s8 DbmToTxPwrIdx(struct r8180_priv *priv, WIRELESS_MODE WirelessMode,
-                s32 PowerInDbm)
+static s8 DbmToTxPwrIdx(struct r8180_priv *priv, WIRELESS_MODE WirelessMode,
+                       s32 PowerInDbm)
 {
        bool bUseDefault = true;
        s8 TxPwrIdx = 0;
index dab787542c45d6d9efc2c67ea2e1dfc16443cc20..098e368835e267467c5e8304d1a372769aa7dde4 100644 (file)
@@ -50,8 +50,9 @@ static int r8180_wx_get_freq(struct net_device *dev,
 }
 
 
-int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
-                    union iwreq_data *wrqu, char *key)
+static int r8180_wx_set_key(struct net_device *dev,
+                           struct iw_request_info *info,
+                           union iwreq_data *wrqu, char *key)
 {
        struct r8180_priv *priv = ieee80211_priv(dev);
        struct iw_point *erq = &(wrqu->encoding);
index 978dc5f4f929f197aa680a407251b6bfa5a6c3d2..43383cf8b161756fb931c268e0895422ef4574c4 100644 (file)
@@ -135,7 +135,7 @@ static void PlatformIOWrite2Byte(struct net_device *dev, u32 offset, u16 data)
 static void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data)
 {
        if (offset == PhyAddr) {
-       /* For Base Band configuration. */
+               /* For Base Band configuration. */
                unsigned char   cmdByte;
                unsigned long   dataBytes;
                unsigned char   idx;
@@ -155,7 +155,7 @@ static void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data)
                /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */
 
                for (idx = 0; idx < 30; idx++) {
-               /* Make sure command bit is clear before access it. */
+                       /* Make sure command bit is clear before access it. */
                        u1bTmp = PlatformIORead1Byte(dev, PhyAddr);
                        if ((u1bTmp & BIT7) == 0)
                                break;
@@ -1296,8 +1296,8 @@ void rtl8185b_rx_enable(struct net_device *dev)
        if (dev->flags & IFF_PROMISC)
                DMESG("NIC in promisc mode");
 
-       if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
-          dev->flags & IFF_PROMISC) {
+       if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || dev->flags &
+           IFF_PROMISC) {
                priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM);
                priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
        }
index 1639a45da948252b3c756b7d28cbe70b185a9f5e..0bd32de44600f901a73cad228d97bce5a5f61e77 100644 (file)
@@ -30,7 +30,6 @@ r8188eu-y :=                          \
                hal/HalPhyRf.o          \
                hal/HalPhyRf_8188e.o    \
                hal/HalPwrSeqCmd.o      \
-               hal/Hal8188EFWImg_CE.o  \
                hal/Hal8188EPwrSeq.o    \
                hal/Hal8188ERateAdaptive.o\
                hal/hal_intf.o          \
index e50aa50bdb478a974e7c04900183620fc05c9d91..f7f389c40e71429d6ee48fd8742dcb7193afab7a 100644 (file)
@@ -2,7 +2,6 @@ TODO:
 - find and remove remaining code valid only for 5 HGz. Most of the obvious
   ones have been removed, but things like channel > 14 still exist.
 - find and remove any code for other chips that is left over
-- convert to external firmware
 - convert any remaining unusual variable types
 - find codes that can use %pM and %Nph formatting
 - checkpatch.pl fixes - most of the remaining ones are lines too long. Many
index 2c73823d2245be5c1a01a40b34696edf318b8b3a..2c678f4095734698b2fcfcdf6318691b7b8c4855 100644 (file)
@@ -348,7 +348,7 @@ void        expire_timeout_chk(struct adapter *padapter)
 
                        if (psta->state & WIFI_SLEEP_STATE) {
                                if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
-                                       /* to check if alive by another methods if staion is at ps mode. */
+                                       /* to check if alive by another methods if station is at ps mode. */
                                        psta->expire_to = pstapriv->expire_to;
                                        psta->state |= WIFI_STA_ALIVE_CHK_STATE;
 
index fbca394cf4fcd5f02073529422ce9a3bace0bda0..9f40742ee5cfe195c7471db2358bd70559d33481 100644 (file)
@@ -527,7 +527,7 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
                case NAT25_CHECK:
                        return -1;
                case NAT25_INSERT:
-                       /* some muticast with source IP is all zero, maybe other case is illegal */
+                       /* some multicast with source IP is all zero, maybe other case is illegal */
                        /* in class A, B, C, host address is all zero or all one is illegal */
                        if (iph->saddr == 0)
                                return 0;
@@ -677,9 +677,8 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method)
                        switch (method) {
                        case NAT25_CHECK:
                                if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN))
-                               DEBUG_INFO("NAT25: Check IPX skb_copy\n");
+                                       DEBUG_INFO("NAT25: Check IPX skb_copy\n");
                                return 0;
-                               return -1;
                        case NAT25_INSERT:
                                DEBUG_INFO("NAT25: Insert IPX, Dest =%08x,%02x%02x%02x%02x%02x%02x,%04x Source =%08x,%02x%02x%02x%02x%02x%02x,%04x\n",
                                        ipx->ipx_dest.net,
index 9632ef48fbc1234877a19d031ade4633d14483ad..f45f4eddb741615774dde3af53e9248bf7a82a03 100644 (file)
@@ -218,7 +218,7 @@ _func_enter_;
 _func_exit_;
 }
 
-int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
+static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
 {
        u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */
 
@@ -1162,7 +1162,7 @@ _func_enter_;
        else
                memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16);
 
-       /* jeff: set this becasue at least sw key is ready */
+       /* jeff: set this because at least sw key is ready */
        padapter->securitypriv.busetkipkey = true;
 
        res = rtw_enqueue_cmd(pcmdpriv, ph2c);
@@ -1667,7 +1667,7 @@ static void traffic_status_watchdog(struct adapter *padapter)
        pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic;
 }
 
-void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz)
+static void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz)
 {
        struct mlme_priv *pmlmepriv;
 
index 869434c4cf6924d012eaae192cf6093a2cd00247..806f56f1c4378195d326450c0cdcd916d8f3b1f2 100644 (file)
@@ -159,7 +159,7 @@ Efuse_CalculateWordCnts(u8 word_en)
 /*  */
 /*     Description: */
 /*             Execute E-Fuse read byte operation. */
-/*             Refered from SD1 Richard. */
+/*             Referred from SD1 Richard. */
 /*  */
 /*     Assumption: */
 /*             1. Boot from E-Fuse and successfully auto-load. */
@@ -214,7 +214,7 @@ ReadEFuseByte(
 /*     Description: */
 /*             1. Execute E-Fuse read byte operation according as map offset and */
 /*                 save to E-Fuse table. */
-/*             2. Refered from SD1 Richard. */
+/*             2. Referred from SD1 Richard. */
 /*  */
 /*     Assumption: */
 /*             1. Boot from E-Fuse and successfully auto-load. */
@@ -542,7 +542,7 @@ u8 rtw_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 {
        u8 offset, word_en;
        u8 *map;
-       u8 newdata[PGPKT_DATA_SIZE];
+       u8 newdata[PGPKT_DATA_SIZE + 1];
        s32     i, idx;
        u8 ret = _SUCCESS;
        u16 mapLen = 0;
@@ -564,7 +564,7 @@ u8 rtw_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data)
 
        offset = (addr >> 3);
        word_en = 0xF;
-       _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE);
+       _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1);
        i = addr & 0x7; /*  index of one package */
        idx = 0;        /*  data index */
 
@@ -634,7 +634,7 @@ u8 rtw_BT_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data
 {
        u8 offset, word_en;
        u8 *map;
-       u8 newdata[PGPKT_DATA_SIZE];
+       u8 newdata[PGPKT_DATA_SIZE + 1];
        s32     i, idx;
        u8 ret = _SUCCESS;
        u16 mapLen = 0;
@@ -656,7 +656,7 @@ u8 rtw_BT_efuse_map_write(struct adapter *padapter, u16 addr, u16 cnts, u8 *data
 
        offset = (addr >> 3);
        word_en = 0xF;
-       _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE);
+       _rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE + 1);
        i = addr & 0x7; /*  index of one package */
        idx = 0;        /*  data index */
 
index 6fc77428e83a0c389c51e6cca52ceaa6a8ff7dd9..e6f98fb8f11353e139f41635d589a11eac64b316 100644 (file)
@@ -1129,7 +1129,7 @@ void rtw_macaddr_cfg(u8 *mac_addr)
                mac[3] = 0x87;
                mac[4] = 0x00;
                mac[5] = 0x00;
-               /*  use default mac addresss */
+               /*  use default mac address */
                memcpy(mac_addr, mac, ETH_ALEN);
                DBG_88E("MAC Address from efuse error, assign default one !!!\n");
        }
index ea6607196d84bb1d22c8fcd474144ee8f699d71d..ac3535d33a45a3a42bbdf42b96cde8cad539cafd 100644 (file)
@@ -557,7 +557,7 @@ _func_enter_;
                        sq_final = ((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5;
                        rssi_final = (src->Rssi+dst->Rssi*4)/5;
                } else {
-                       /* bss info not receving from the right channel, use the original RX signal infos */
+                       /* bss info not receiving from the right channel, use the original RX signal infos */
                        ss_final = dst->PhyInfo.SignalStrength;
                        sq_final = dst->PhyInfo.SignalQuality;
                        rssi_final = dst->Rssi;
@@ -636,7 +636,7 @@ _func_enter_;
                        pnetwork->aid = 0;
                        pnetwork->join_res = 0;
 
-                       /* bss info not receving from the right channel */
+                       /* bss info not receiving from the right channel */
                        if (pnetwork->network.PhyInfo.SignalQuality == 101)
                                pnetwork->network.PhyInfo.SignalQuality = 0;
                } else {
@@ -656,7 +656,7 @@ _func_enter_;
 
                        pnetwork->last_scanned = rtw_get_current_time();
 
-                       /* bss info not receving from the right channel */
+                       /* bss info not receiving from the right channel */
                        if (pnetwork->network.PhyInfo.SignalQuality == 101)
                                pnetwork->network.PhyInfo.SignalQuality = 0;
                        rtw_list_insert_tail(&(pnetwork->list), &(queue->queue));
@@ -670,7 +670,7 @@ _func_enter_;
 
                pnetwork->last_scanned = rtw_get_current_time();
 
-               /* target.Reserved[0]== 1, means that scaned network is a bcn frame. */
+               /* target.Reserved[0]== 1, means that scanned network is a bcn frame. */
                if ((pnetwork->network.IELength > target->IELength) && (target->Reserved[0] == 1))
                        update_ie = false;
 
@@ -1130,7 +1130,7 @@ static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, str
                        padapter->securitypriv.wps_ie_len = 0;
                }
                /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info */
-               /* if A-MPDU Rx is enabled, reseting  rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
+               /* if A-MPDU Rx is enabled, resetting  rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */
                /* todo: check if AP can send A-MPDU packets */
                for (i = 0; i < 16; i++) {
                        /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
@@ -1210,7 +1210,7 @@ static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_net
        rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength);
 }
 
-/* Notes: the fucntion could be > passive_level (the same context as Rx tasklet) */
+/* Notes: the function could be > passive_level (the same context as Rx tasklet) */
 /* pnetwork: returns from rtw_joinbss_event_callback */
 /* ptarget_wlan: found from scanned_queue */
 /* if join_res > 0, for (fw_state == WIFI_STATION_STATE), we check if  "ptarget_sta" & "ptarget_wlan" exist. */
@@ -2177,7 +2177,7 @@ _func_enter_;
 _func_exit_;
 }
 
-/* the fucntion is at passive_level */
+/* the function is at passive_level */
 void rtw_joinbss_reset(struct adapter *padapter)
 {
        u8      threshold;
@@ -2205,7 +2205,7 @@ void rtw_joinbss_reset(struct adapter *padapter)
        }
 }
 
-/* the fucntion is >= passive_level */
+/* the function is >= passive_level */
 unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len)
 {
        u32 ielen, out_len;
@@ -2273,7 +2273,7 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_
        return phtpriv->ht_option;
 }
 
-/* the fucntion is > passive_level (in critical_section) */
+/* the function is > passive_level (in critical_section) */
 void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len)
 {
        u8 *p, max_ampdu_sz;
@@ -2332,7 +2332,7 @@ void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len)
                        else
                                pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
                }
-               /* switch to the 40M Hz mode accoring to the AP */
+               /* switch to the 40M Hz mode according to the AP */
                pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
                switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
                case HT_EXTCHNL_OFFSET_UPPER:
index 4b2eb8e9b5620ab4529ec9ce8af252ef502a65fc..9982dd0e2060185359b5fb0404511cb5784bcee4 100644 (file)
@@ -2349,7 +2349,7 @@ static void issue_p2p_GO_response(struct adapter *padapter, u8 *raddr, u8 *frame
        if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
                /*      Commented by Albert 2011/03/08 */
                /*      According to the P2P specification */
-               /*      if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
+               /*      if the sending device will be client, the P2P Capability should be reserved of group negotiation response frame */
                p2pie[p2pielen++] = 0;
        } else {
                /*      Be group owner or meet the error case */
@@ -6698,7 +6698,7 @@ u8 collect_bss_info(struct adapter *padapter, union recv_frame *precv_frame, str
                }
        }
 
-       /*  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;
        return _SUCCESS;
@@ -8110,7 +8110,7 @@ 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 */
 #ifdef CONFIG_88EU_P2P
                if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
                        initialgain = 0x1E;
index 201165787362b6ea9d1b2a7613b1c8d7457dffe0..9f0f30f7069a92be71028f670c0aff9173b742be 100644 (file)
@@ -204,11 +204,14 @@ void rtw_init_recvframe(union recv_frame *precvframe, struct recv_priv *precvpri
 int rtw_free_recvframe(union recv_frame *precvframe, struct __queue *pfree_recv_queue)
 {
        unsigned long irqL;
-       struct adapter *padapter = precvframe->u.hdr.adapter;
-       struct recv_priv *precvpriv = &padapter->recvpriv;
+       struct adapter *padapter;
+       struct recv_priv *precvpriv;
 
 _func_enter_;
-
+       if (!precvframe)
+               return _FAIL;
+       padapter = precvframe->u.hdr.adapter;
+       precvpriv = &padapter->recvpriv;
        if (precvframe->u.hdr.pkt) {
                dev_kfree_skb_any(precvframe->u.hdr.pkt);/* free skb by driver */
                precvframe->u.hdr.pkt = NULL;
@@ -1583,7 +1586,7 @@ _func_enter_;
 
                pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
                plist = get_next(plist);
-       };
+       }
 
        /* free the defrag_q queue and return the prframe */
        rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
@@ -1798,16 +1801,14 @@ static int amsdu_to_msdu(struct adapter *padapter, union recv_frame *prframe)
                        memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
                }
 
-               /* Indicat the packets to upper layer */
-               if (sub_skb) {
-                       /*  Insert NAT2.5 RX here! */
-                       sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
-                       sub_skb->dev = padapter->pnetdev;
+               /* Indicate the packets to upper layer */
+               /*  Insert NAT2.5 RX here! */
+               sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
+               sub_skb->dev = padapter->pnetdev;
 
-                       sub_skb->ip_summed = CHECKSUM_NONE;
+               sub_skb->ip_summed = CHECKSUM_NONE;
 
-                       netif_rx(sub_skb);
-               }
+               netif_rx(sub_skb);
        }
 
 exit:
index 0f076d0cb5f8571227b8fc58d68a407e22f5863d..e08845729772ff4377decd805a2f6b57cd8d9235 100644 (file)
@@ -916,7 +916,7 @@ _func_enter_;
                        add1b[i] = 0x00;
        }
 
-       swap_halfs[0] = in[2];    /* Swap halfs */
+       swap_halfs[0] = in[2];    /* Swap halves */
        swap_halfs[1] = in[3];
        swap_halfs[2] = in[0];
        swap_halfs[3] = in[1];
index c2977be92fb14d3d4d7f2892b3c9f5baa9c954f7..cd3c9a7c3044c26ea626bf1b8e89070aeedaa3c4 100644 (file)
@@ -267,9 +267,8 @@ _func_enter_;
 
                rtw_mfree_sta_priv_lock(pstapriv);
 
-               if (pstapriv->pallocated_stainfo_buf) {
+               if (pstapriv->pallocated_stainfo_buf)
                        rtw_vmfree(pstapriv->pallocated_stainfo_buf, sizeof(struct sta_info)*NUM_STA+4);
-               }
        }
 
 _func_exit_;
@@ -315,7 +314,7 @@ _func_enter_;
 
                rtw_list_insert_tail(&psta->hash_list, phash_list);
 
-               pstapriv->asoc_sta_count++ ;
+               pstapriv->asoc_sta_count++;
 
                _exit_critical_bh(&(pstapriv->sta_hash_lock), &irql2);
 
@@ -419,7 +418,7 @@ _func_enter_;
        _cancel_timer_ex(&psta->addba_retry_timer);
 
        /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
-       for (i = 0; i < 16 ; i++) {
+       for (i = 0; i < 16; i++) {
                unsigned long irql;
                struct list_head *phead, *plist;
                union recv_frame *prframe;
index 8018edd3d42e19fcc0875c7324584d94e6fb02ad..153ec61493ab6ef94a4ec71f886b8a700ecad4ad 100644 (file)
@@ -80,7 +80,7 @@ int cckratesonly_included(unsigned char *rate, int ratelen)
        for (i = 0; i < ratelen; i++) {
                if  ((((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
                           (((rate[i]) & 0x7f) != 11)  && (((rate[i]) & 0x7f) != 22))
-               return false;
+                       return false;
        }
 
        return true;
@@ -766,7 +766,7 @@ void HT_caps_handler(struct adapter *padapter, struct ndis_802_11_var_ie *pIE)
 
        for (i = 0; i < (pIE->Length); i++) {
                if (i != 2) {
-                       /*      Got the endian issue here. */
+                       /*      Got the endian issue here. */
                        pmlmeinfo->HT_caps.u.HT_cap[i] &= (pIE->data[i]);
                } else {
                        /* modify from  fw by Thomas 2010/11/17 */
@@ -1096,13 +1096,13 @@ int rtw_check_bcn_info(struct adapter  *Adapter, u8 *pframe, u32 packet_len)
        }
 
        kfree(bssid);
+       _func_exit_;
        return _SUCCESS;
 
 _mismatch:
        kfree(bssid);
-       return _FAIL;
-
        _func_exit_;
+       return _FAIL;
 }
 
 void update_beacon_info(struct adapter *padapter, u8 *pframe, uint pkt_len, struct sta_info *psta)
@@ -1186,7 +1186,7 @@ unsigned int should_forbid_n_rate(struct adapter *padapter)
                        case _RSN_IE_2_:
                                if  ((_rtw_memcmp((pIE->data + 8), RSN_CIPHER_SUITE_CCMP, 4))  ||
                                       (_rtw_memcmp((pIE->data + 12), RSN_CIPHER_SUITE_CCMP, 4)))
-                               return false;
+                                       return false;
                        default:
                                break;
                        }
@@ -1368,21 +1368,21 @@ void update_tx_basic_rate(struct adapter *padapter, u8 wirelessmode)
 #ifdef CONFIG_88EU_P2P
        struct wifidirect_info *pwdinfo = &padapter->wdinfo;
 
-       /*      Added by Albert 2011/03/22 */
-       /*      In the P2P mode, the driver should not support the b mode. */
-       /*      So, the Tx packet shouldn't use the CCK rate */
+       /*      Added by Albert 2011/03/22 */
+       /*      In the P2P mode, the driver should not support the b mode. */
+       /*      So, the Tx packet shouldn't use the CCK rate */
        if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
                return;
 #endif /* CONFIG_88EU_P2P */
        _rtw_memset(supported_rates, 0, NDIS_802_11_LENGTH_RATES_EX);
 
-       if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B)) {
+       if ((wirelessmode & WIRELESS_11B) && (wirelessmode == WIRELESS_11B))
                memcpy(supported_rates, rtw_basic_rate_cck, 4);
-       } else if (wirelessmode & WIRELESS_11B) {
+       else if (wirelessmode & WIRELESS_11B)
                memcpy(supported_rates, rtw_basic_rate_mix, 7);
-       } else {
+       else
                memcpy(supported_rates, rtw_basic_rate_ofdm, 3);
-       }
+
 
        if (wirelessmode & WIRELESS_11B)
                update_mgnt_tx_rate(padapter, IEEE80211_CCK_RATE_1MB);
@@ -1435,7 +1435,7 @@ unsigned char check_assoc_AP(u8 *pframe, uint len)
                                DBG_88E("link to Airgo Cap\n");
                                return HT_IOT_PEER_AIRGO;
                        } else if (_rtw_memcmp(pIE->data, EPIGRAM_OUI, 3)) {
-                                epigram_vendor_flag = 1;
+                               epigram_vendor_flag = 1;
                                if (ralink_vendor_flag) {
                                        DBG_88E("link to Tenda W311R AP\n");
                                         return HT_IOT_PEER_TENDA;
index bb5cd95c564e2089897457f0c066a3ae16850b37..a594e51d2e1ca974b9bb946b56e9e9457c533c2e 100644 (file)
@@ -1556,7 +1556,7 @@ static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, str
        xmitframe_phead = get_list_head(pframe_queue);
        xmitframe_plist = get_next(xmitframe_phead);
 
-       while (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
+       if (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
                pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
 
                xmitframe_plist = get_next(xmitframe_plist);
@@ -1564,12 +1564,7 @@ static struct xmit_frame *dequeue_one_xmitframe(struct xmit_priv *pxmitpriv, str
                rtw_list_delete(&pxmitframe->list);
 
                ptxservq->qcnt--;
-
-               break;
-
-               pxmitframe = NULL;
        }
-
        return pxmitframe;
 }
 
diff --git a/drivers/staging/rtl8188eu/hal/Hal8188EFWImg_CE.c b/drivers/staging/rtl8188eu/hal/Hal8188EFWImg_CE.c
deleted file mode 100644 (file)
index 95759be..0000000
+++ /dev/null
@@ -1,1761 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License as
-* published by the Free Software Foundation.
-*
-* 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.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
-*
-*
-******************************************************************************/
-#include "odm_precomp.h"
-
-const u8 Rtl8188EFwImgArray[Rtl8188EFWImgArrayLength] = {
-       0xE1, 0x88, 0x10, 0x00, 0x0B, 0x00, 0x01, 0x00,
-       0x01, 0x21, 0x11, 0x27, 0x30, 0x36, 0x00, 0x00,
-       0x2D, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x02, 0x45, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xC1, 0x6F, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0xA1, 0xE6, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x02, 0x56, 0xF7, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0xC2, 0xAF, 0x80, 0xFE, 0x32, 0x12, 0x42, 0x04,
-       0x85, 0xD0, 0x0B, 0x75, 0xD0, 0x08, 0xAA, 0xE0,
-       0xC2, 0x8C, 0xE5, 0x8A, 0x24, 0x67, 0xF5, 0x8A,
-       0xE5, 0x8C, 0x34, 0x79, 0xF5, 0x8C, 0xD2, 0x8C,
-       0xEC, 0x24, 0x89, 0xF8, 0xE6, 0xBC, 0x03, 0x02,
-       0x74, 0xFF, 0xC3, 0x95, 0x81, 0xB4, 0x40, 0x00,
-       0x40, 0xCE, 0x79, 0x04, 0x78, 0x80, 0x16, 0xE6,
-       0x08, 0x70, 0x0B, 0xC2, 0xAF, 0xE6, 0x30, 0xE1,
-       0x03, 0x44, 0x18, 0xF6, 0xD2, 0xAF, 0x08, 0xD9,
-       0xED, 0xEA, 0x8B, 0xD0, 0x22, 0xE5, 0x0C, 0xFF,
-       0x23, 0x24, 0x81, 0xF8, 0x0F, 0x08, 0x08, 0xBF,
-       0x04, 0x04, 0x7F, 0x00, 0x78, 0x81, 0xE6, 0x30,
-       0xE4, 0xF2, 0x00, 0xE5, 0x0C, 0xC3, 0x9F, 0x50,
-       0x20, 0x05, 0x0C, 0x74, 0x88, 0x25, 0x0C, 0xF8,
-       0xE6, 0xFD, 0xA6, 0x81, 0x08, 0xE6, 0xAE, 0x0C,
-       0xBE, 0x03, 0x02, 0x74, 0xFF, 0xCD, 0xF8, 0xE8,
-       0x6D, 0x60, 0xE0, 0x08, 0xE6, 0xC0, 0xE0, 0x80,
-       0xF6, 0xE5, 0x0C, 0xD3, 0x9F, 0x40, 0x27, 0xE5,
-       0x0C, 0x24, 0x89, 0xF8, 0xE6, 0xAE, 0x0C, 0xBE,
-       0x03, 0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xCD,
-       0xF8, 0xE5, 0x81, 0x6D, 0x60, 0x06, 0xD0, 0xE0,
-       0xF6, 0x18, 0x80, 0xF5, 0xE5, 0x0C, 0x24, 0x88,
-       0xC8, 0xF6, 0x15, 0x0C, 0x80, 0xD3, 0xE5, 0x0C,
-       0x23, 0x24, 0x81, 0xF8, 0x7F, 0x04, 0xC2, 0xAF,
-       0xE6, 0x30, 0xE0, 0x03, 0x10, 0xE2, 0x0C, 0x7F,
-       0x00, 0x30, 0xE1, 0x07, 0x30, 0xE3, 0x04, 0x7F,
-       0x08, 0x54, 0xF4, 0x54, 0x7C, 0xC6, 0xD2, 0xAF,
-       0x54, 0x80, 0x42, 0x07, 0x22, 0x78, 0x88, 0xA6,
-       0x81, 0x74, 0x03, 0x60, 0x06, 0xFF, 0x08, 0x76,
-       0xFF, 0xDF, 0xFB, 0x7F, 0x04, 0xE4, 0x78, 0x80,
-       0xF6, 0x08, 0xF6, 0x08, 0xDF, 0xFA, 0x78, 0x81,
-       0x76, 0x30, 0x90, 0x45, 0xDE, 0x74, 0x01, 0x93,
-       0xC0, 0xE0, 0xE4, 0x93, 0xC0, 0xE0, 0x43, 0x89,
-       0x01, 0x75, 0x8A, 0x60, 0x75, 0x8C, 0x79, 0xD2,
-       0x8C, 0xD2, 0xAF, 0x22, 0x03, 0xEF, 0xD3, 0x94,
-       0x03, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0x74, 0x81,
-       0x2F, 0x2F, 0xF8, 0xE6, 0x20, 0xE5, 0xF4, 0xC2,
-       0xAF, 0xE6, 0x44, 0x30, 0xF6, 0xD2, 0xAF, 0xAE,
-       0x0C, 0xEE, 0xC3, 0x9F, 0x50, 0x21, 0x0E, 0x74,
-       0x88, 0x2E, 0xF8, 0xE6, 0xF9, 0x08, 0xE6, 0x18,
-       0xBE, 0x03, 0x02, 0x74, 0xFF, 0xFD, 0xED, 0x69,
-       0x60, 0x09, 0x09, 0xE7, 0x19, 0x19, 0xF7, 0x09,
-       0x09, 0x80, 0xF3, 0x16, 0x16, 0x80, 0xDA, 0xEE,
-       0xD3, 0x9F, 0x40, 0x04, 0x05, 0x81, 0x05, 0x81,
-       0xEE, 0xD3, 0x9F, 0x40, 0x22, 0x74, 0x88, 0x2E,
-       0xF8, 0x08, 0xE6, 0xF9, 0xEE, 0xB5, 0x0C, 0x02,
-       0xA9, 0x81, 0x18, 0x06, 0x06, 0xE6, 0xFD, 0xED,
-       0x69, 0x60, 0x09, 0x19, 0x19, 0xE7, 0x09, 0x09,
-       0xF7, 0x19, 0x80, 0xF3, 0x1E, 0x80, 0xD9, 0xEF,
-       0x24, 0x88, 0xF8, 0xE6, 0x04, 0xF8, 0xEF, 0x2F,
-       0x04, 0x90, 0x45, 0xDE, 0x93, 0xF6, 0x08, 0xEF,
-       0x2F, 0x93, 0xF6, 0x7F, 0x00, 0x22, 0xEF, 0xD3,
-       0x94, 0x03, 0x40, 0x03, 0x7F, 0xFF, 0x22, 0xEF,
-       0x23, 0x24, 0x81, 0xF8, 0xE6, 0x30, 0xE5, 0xF4,
-       0xC2, 0xAF, 0xE6, 0x54, 0x8C, 0xF6, 0xD2, 0xAF,
-       0xE5, 0x0C, 0xB5, 0x07, 0x0A, 0x74, 0x88, 0x2F,
-       0xF8, 0xE6, 0xF5, 0x81, 0x02, 0x42, 0x4D, 0x50,
-       0x2E, 0x74, 0x89, 0x2F, 0xF8, 0xE6, 0xBF, 0x03,
-       0x02, 0x74, 0xFF, 0xFD, 0x18, 0xE6, 0xF9, 0x74,
-       0x88, 0x2F, 0xF8, 0xFB, 0xE6, 0xFC, 0xE9, 0x6C,
-       0x60, 0x08, 0xA8, 0x05, 0xE7, 0xF6, 0x1D, 0x19,
-       0x80, 0xF4, 0xA8, 0x03, 0xA6, 0x05, 0x1F, 0xE5,
-       0x0C, 0xB5, 0x07, 0xE3, 0x7F, 0x00, 0x22, 0x74,
-       0x89, 0x2F, 0xF8, 0xE6, 0xFD, 0x18, 0x86, 0x01,
-       0x0F, 0x74, 0x88, 0x2F, 0xF8, 0xA6, 0x01, 0x08,
-       0x86, 0x04, 0xE5, 0x0C, 0xB5, 0x07, 0x02, 0xAC,
-       0x81, 0xED, 0x6C, 0x60, 0x08, 0x0D, 0x09, 0xA8,
-       0x05, 0xE6, 0xF7, 0x80, 0xF4, 0xE5, 0x0C, 0xB5,
-       0x07, 0xDE, 0x89, 0x81, 0x7F, 0x00, 0x22, 0xEF,
-       0xD3, 0x94, 0x03, 0x40, 0x03, 0x7F, 0xFF, 0x22,
-       0xEF, 0x23, 0x24, 0x81, 0xF8, 0xC2, 0xAF, 0xE6,
-       0x30, 0xE5, 0x05, 0x30, 0xE0, 0x02, 0xD2, 0xE4,
-       0xD2, 0xE2, 0xC6, 0xD2, 0xAF, 0x7F, 0x00, 0x30,
-       0xE2, 0x01, 0x0F, 0x02, 0x42, 0x4C, 0x8F, 0xF0,
-       0xE4, 0xFF, 0xFE, 0xE5, 0x0C, 0x23, 0x24, 0x80,
-       0xF8, 0xC2, 0xA9, 0x30, 0xF7, 0x0D, 0x7F, 0x08,
-       0xE6, 0x60, 0x0B, 0x2D, 0xF6, 0x60, 0x30, 0x50,
-       0x2E, 0x80, 0x07, 0x30, 0xF1, 0x06, 0xED, 0xF6,
-       0x60, 0x25, 0x7E, 0x02, 0x08, 0x30, 0xF0, 0x10,
-       0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x23, 0x0E, 0x30,
-       0xE2, 0x0C, 0xD2, 0xAF, 0x7F, 0x04, 0x80, 0x12,
-       0xC2, 0xAF, 0xE6, 0x10, 0xE7, 0x13, 0x54, 0xEC,
-       0x4E, 0xF6, 0xD2, 0xAF, 0x02, 0x42, 0x4D, 0x7F,
-       0x08, 0x08, 0xEF, 0x44, 0x83, 0xF4, 0xC2, 0xAF,
-       0x56, 0xC6, 0xD2, 0xAF, 0x54, 0x80, 0x4F, 0xFF,
-       0x22, 0xC5, 0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0,
-       0xC5, 0xF0, 0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70,
-       0x02, 0x15, 0x83, 0xE0, 0x38, 0xF0, 0x22, 0xEF,
-       0x5B, 0xFF, 0xEE, 0x5A, 0xFE, 0xED, 0x59, 0xFD,
-       0xEC, 0x58, 0xFC, 0x22, 0xEF, 0x4B, 0xFF, 0xEE,
-       0x4A, 0xFE, 0xED, 0x49, 0xFD, 0xEC, 0x48, 0xFC,
-       0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xFD, 0xA3, 0xE0,
-       0xFE, 0xA3, 0xE0, 0xFF, 0x22, 0xE2, 0xFC, 0x08,
-       0xE2, 0xFD, 0x08, 0xE2, 0xFE, 0x08, 0xE2, 0xFF,
-       0x22, 0xE2, 0xFB, 0x08, 0xE2, 0xF9, 0x08, 0xE2,
-       0xFA, 0x08, 0xE2, 0xCB, 0xF8, 0x22, 0xEC, 0xF2,
-       0x08, 0xED, 0xF2, 0x08, 0xEE, 0xF2, 0x08, 0xEF,
-       0xF2, 0x22, 0xA4, 0x25, 0x82, 0xF5, 0x82, 0xE5,
-       0xF0, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB,
-       0xA3, 0xE0, 0xFA, 0xA3, 0xE0, 0xF9, 0x22, 0xEB,
-       0xF0, 0xA3, 0xEA, 0xF0, 0xA3, 0xE9, 0xF0, 0x22,
-       0xD0, 0x83, 0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70,
-       0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3,
-       0x93, 0xF8, 0x74, 0x01, 0x93, 0xF5, 0x82, 0x88,
-       0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60,
-       0xEF, 0xA3, 0xA3, 0xA3, 0x80, 0xDF, 0x02, 0x45,
-       0x8C, 0x02, 0x42, 0xDD, 0xE4, 0x93, 0xA3, 0xF8,
-       0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, 0x80, 0x01,
-       0xF2, 0x08, 0xDF, 0xF4, 0x80, 0x29, 0xE4, 0x93,
-       0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3,
-       0x33, 0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83,
-       0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6,
-       0xDF, 0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08,
-       0x10, 0x20, 0x40, 0x80, 0x90, 0x45, 0xD1, 0xE4,
-       0x7E, 0x01, 0x93, 0x60, 0xBC, 0xA3, 0xFF, 0x54,
-       0x3F, 0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE, 0xE4,
-       0x93, 0xA3, 0x60, 0x01, 0x0E, 0xCF, 0x54, 0xC0,
-       0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8, 0xE4, 0x93,
-       0xA3, 0xFA, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93,
-       0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83,
-       0xCA, 0xF0, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA,
-       0xC5, 0x83, 0xCA, 0xDF, 0xE9, 0xDE, 0xE7, 0x80,
-       0xBE, 0x00, 0x41, 0x82, 0x09, 0x00, 0x41, 0x82,
-       0x0A, 0x00, 0x41, 0x82, 0x17, 0x00, 0x59, 0xE2,
-       0x5C, 0x24, 0x5E, 0x5D, 0x5F, 0xA1, 0xC0, 0xE0,
-       0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0, 0xD0,
-       0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01, 0xC0,
-       0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
-       0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74, 0xE6,
-       0xF0, 0x74, 0x45, 0xA3, 0xF0, 0xD1, 0x35, 0x74,
-       0xE6, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x45,
-       0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05,
-       0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
-       0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83,
-       0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90, 0x00, 0x54,
-       0xE0, 0x55, 0x35, 0xF5, 0x39, 0xA3, 0xE0, 0x55,
-       0x36, 0xF5, 0x3A, 0xA3, 0xE0, 0x55, 0x37, 0xF5,
-       0x3B, 0xA3, 0xE0, 0x55, 0x38, 0xF5, 0x3C, 0xAD,
-       0x39, 0x7F, 0x54, 0x12, 0x32, 0x1E, 0xAD, 0x3A,
-       0x7F, 0x55, 0x12, 0x32, 0x1E, 0xAD, 0x3B, 0x7F,
-       0x56, 0x12, 0x32, 0x1E, 0xAD, 0x3C, 0x7F, 0x57,
-       0x12, 0x32, 0x1E, 0x53, 0x91, 0xEF, 0x22, 0xC0,
-       0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0,
-       0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01,
-       0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05,
-       0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74,
-       0x6F, 0xF0, 0x74, 0x46, 0xA3, 0xF0, 0x12, 0x6C,
-       0x78, 0xE5, 0x41, 0x30, 0xE4, 0x04, 0x7F, 0x02,
-       0x91, 0x27, 0xE5, 0x41, 0x30, 0xE6, 0x03, 0x12,
-       0x6C, 0xD5, 0xE5, 0x43, 0x30, 0xE0, 0x03, 0x12,
-       0x51, 0xC2, 0xE5, 0x43, 0x30, 0xE1, 0x03, 0x12,
-       0x4D, 0x0C, 0xE5, 0x43, 0x30, 0xE2, 0x03, 0x12,
-       0x4C, 0xC1, 0xE5, 0x43, 0x30, 0xE3, 0x03, 0x12,
-       0x6C, 0xE2, 0xE5, 0x43, 0x30, 0xE4, 0x03, 0x12,
-       0x6D, 0x04, 0xE5, 0x43, 0x30, 0xE5, 0x03, 0x12,
-       0x6D, 0x33, 0xE5, 0x43, 0x30, 0xE6, 0x02, 0xF1,
-       0x0F, 0xE5, 0x44, 0x30, 0xE1, 0x03, 0x12, 0x51,
-       0x7F, 0x74, 0x6F, 0x04, 0x90, 0x01, 0xC4, 0xF0,
-       0x74, 0x46, 0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06,
-       0xD0, 0x05, 0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02,
-       0xD0, 0x01, 0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82,
-       0xD0, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90,
-       0x80, 0xDE, 0xE0, 0xB4, 0x01, 0x13, 0x90, 0x81,
-       0x27, 0xE0, 0x60, 0x0D, 0x90, 0x81, 0x2B, 0xE0,
-       0x54, 0xFE, 0xF0, 0x54, 0x07, 0x70, 0x02, 0xF1,
-       0x2A, 0x22, 0x90, 0x81, 0x1F, 0xE0, 0x90, 0x81,
-       0x29, 0x30, 0xE0, 0x05, 0xE0, 0xFF, 0x02, 0x74,
-       0x8F, 0xE0, 0xFF, 0x7D, 0x01, 0xD3, 0x10, 0xAF,
-       0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82, 0x13, 0xED,
-       0xF0, 0x90, 0x81, 0x2A, 0xE0, 0x90, 0x82, 0x14,
-       0xF0, 0x90, 0x81, 0x24, 0xE0, 0xFE, 0xC4, 0x13,
-       0x13, 0x54, 0x03, 0x30, 0xE0, 0x03, 0x02, 0x48,
-       0xA0, 0xEE, 0xC4, 0x13, 0x13, 0x13, 0x54, 0x01,
-       0x30, 0xE0, 0x03, 0x02, 0x48, 0xA0, 0x90, 0x82,
-       0x14, 0xE0, 0xFE, 0x6F, 0x70, 0x03, 0x02, 0x48,
-       0xA0, 0xEF, 0x70, 0x03, 0x02, 0x48, 0x17, 0x24,
-       0xFE, 0x70, 0x03, 0x02, 0x48, 0x50, 0x24, 0xFE,
-       0x60, 0x51, 0x24, 0xFC, 0x70, 0x03, 0x02, 0x48,
-       0x8B, 0x24, 0xFC, 0x60, 0x03, 0x02, 0x48, 0xA0,
-       0xEE, 0xB4, 0x0E, 0x03, 0x12, 0x49, 0x5E, 0x90,
-       0x82, 0x14, 0xE0, 0x70, 0x05, 0x7F, 0x01, 0x12,
-       0x49, 0x93, 0x90, 0x82, 0x14, 0xE0, 0xB4, 0x06,
-       0x03, 0x12, 0x49, 0x34, 0x90, 0x82, 0x14, 0xE0,
-       0xB4, 0x04, 0x0F, 0x90, 0x82, 0x13, 0xE0, 0xFF,
-       0x60, 0x05, 0x12, 0x73, 0x75, 0x80, 0x03, 0x12,
-       0x66, 0x26, 0x90, 0x82, 0x14, 0xE0, 0x64, 0x08,
-       0x60, 0x03, 0x02, 0x48, 0xA0, 0x12, 0x73, 0xD3,
-       0x02, 0x48, 0xA0, 0x90, 0x82, 0x14, 0xE0, 0x70,
-       0x05, 0x7F, 0x01, 0x12, 0x49, 0x93, 0x90, 0x82,
-       0x14, 0xE0, 0xB4, 0x06, 0x03, 0x12, 0x49, 0x34,
-       0x90, 0x82, 0x14, 0xE0, 0xB4, 0x0E, 0x09, 0x12,
-       0x48, 0xA5, 0xBF, 0x01, 0x03, 0x12, 0x49, 0x5E,
-       0x90, 0x82, 0x14, 0xE0, 0x64, 0x0C, 0x60, 0x02,
-       0x01, 0xA0, 0x11, 0xA5, 0xEF, 0x64, 0x01, 0x60,
-       0x02, 0x01, 0xA0, 0x11, 0xFA, 0x01, 0xA0, 0x90,
-       0x82, 0x14, 0xE0, 0xB4, 0x0E, 0x07, 0x11, 0xA5,
-       0xBF, 0x01, 0x02, 0x31, 0x5E, 0x90, 0x82, 0x14,
-       0xE0, 0xB4, 0x06, 0x02, 0x31, 0x34, 0x90, 0x82,
-       0x14, 0xE0, 0xB4, 0x0C, 0x07, 0x11, 0xA5, 0xBF,
-       0x01, 0x02, 0x11, 0xFA, 0x90, 0x82, 0x14, 0xE0,
-       0x64, 0x04, 0x70, 0x5C, 0x12, 0x72, 0xF5, 0xEF,
-       0x64, 0x01, 0x70, 0x54, 0x31, 0xBE, 0x80, 0x50,
-       0x90, 0x82, 0x14, 0xE0, 0xB4, 0x0E, 0x07, 0x11,
-       0xA5, 0xBF, 0x01, 0x02, 0x31, 0x5E, 0x90, 0x82,
-       0x14, 0xE0, 0xB4, 0x06, 0x02, 0x31, 0x34, 0x90,
-       0x82, 0x14, 0xE0, 0xB4, 0x0C, 0x07, 0x11, 0xA5,
-       0xBF, 0x01, 0x02, 0x11, 0xFA, 0x90, 0x82, 0x14,
-       0xE0, 0x70, 0x04, 0x7F, 0x01, 0x31, 0x93, 0x90,
-       0x82, 0x14, 0xE0, 0xB4, 0x04, 0x1A, 0x12, 0x73,
-       0xBB, 0x80, 0x15, 0x90, 0x82, 0x14, 0xE0, 0xB4,
-       0x0C, 0x0E, 0x90, 0x81, 0x25, 0xE0, 0xFF, 0x13,
-       0x13, 0x54, 0x3F, 0x30, 0xE0, 0x02, 0x31, 0xB1,
-       0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD1, 0xAB, 0xEF,
-       0x64, 0x01, 0x60, 0x08, 0x90, 0x01, 0xB8, 0x74,
-       0x01, 0xF0, 0x80, 0x3D, 0x90, 0x81, 0x24, 0xE0,
-       0xFF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0,
-       0x08, 0x90, 0x01, 0xB8, 0x74, 0x02, 0xF0, 0x80,
-       0x28, 0xEF, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x08,
-       0x90, 0x01, 0xB8, 0x74, 0x04, 0xF0, 0x80, 0x19,
-       0x90, 0x81, 0x29, 0xE0, 0xD3, 0x94, 0x04, 0x40,
-       0x08, 0x90, 0x01, 0xB8, 0x74, 0x08, 0xF0, 0x80,
-       0x08, 0x90, 0x01, 0xB8, 0xE4, 0xF0, 0x7F, 0x01,
-       0x22, 0x90, 0x01, 0xB9, 0x74, 0x02, 0xF0, 0x7F,
-       0x00, 0x22, 0x90, 0x80, 0xDE, 0xE0, 0x64, 0x01,
-       0x70, 0x31, 0x90, 0x81, 0x25, 0xE0, 0x54, 0xFD,
-       0xF0, 0x90, 0x05, 0x22, 0x74, 0x6F, 0xF0, 0x7F,
-       0x01, 0xF1, 0x0D, 0xBF, 0x01, 0x12, 0x90, 0x81,
-       0x24, 0xE0, 0x44, 0x80, 0xF0, 0x90, 0x81, 0x2A,
-       0x74, 0x0E, 0xF0, 0x90, 0x81, 0x23, 0xF0, 0x22,
-       0x90, 0x01, 0xB9, 0x74, 0x01, 0xF0, 0x90, 0x01,
-       0xB8, 0x04, 0xF0, 0x22, 0x90, 0x81, 0x25, 0xE0,
-       0x90, 0x06, 0x04, 0x20, 0xE0, 0x0C, 0xE0, 0x44,
-       0x40, 0xF0, 0x90, 0x81, 0x2A, 0x74, 0x04, 0xF0,
-       0x80, 0x0E, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x81,
-       0x2A, 0x74, 0x0C, 0xF0, 0x90, 0x81, 0x23, 0xF0,
-       0x90, 0x05, 0x22, 0xE4, 0xF0, 0x22, 0x90, 0x81,
-       0x25, 0xE0, 0xC3, 0x13, 0x20, 0xE0, 0x08, 0x90,
-       0x81, 0x2A, 0x74, 0x0C, 0xF0, 0x80, 0x1E, 0x90,
-       0x06, 0x04, 0xE0, 0x44, 0x40, 0xF0, 0xE0, 0x44,
-       0x80, 0xF0, 0x90, 0x81, 0x2A, 0x74, 0x04, 0xF0,
-       0x90, 0x05, 0x27, 0xE0, 0x44, 0x80, 0xF0, 0x90,
-       0x81, 0x23, 0x74, 0x04, 0xF0, 0x90, 0x05, 0x22,
-       0xE4, 0xF0, 0x22, 0x90, 0x82, 0x15, 0xEF, 0xF0,
-       0x12, 0x54, 0x65, 0x90, 0x82, 0x15, 0xE0, 0x60,
-       0x05, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x81,
-       0x2A, 0x74, 0x04, 0xF0, 0x90, 0x81, 0x23, 0xF0,
-       0x22, 0x31, 0xE3, 0x90, 0x81, 0x2A, 0x74, 0x08,
-       0xF0, 0x90, 0x81, 0x23, 0xF0, 0x22, 0x90, 0x05,
-       0x22, 0x74, 0xFF, 0xF0, 0xF1, 0x3A, 0x90, 0x01,
-       0x37, 0x74, 0x02, 0xF0, 0xFD, 0x7F, 0x03, 0x51,
-       0x57, 0x31, 0xE3, 0xE4, 0x90, 0x81, 0x2A, 0xF0,
-       0x90, 0x81, 0x23, 0xF0, 0x22, 0x90, 0x05, 0x22,
-       0x74, 0xFF, 0xF0, 0xF1, 0x3A, 0x90, 0x85, 0xBB,
-       0x12, 0x20, 0xDA, 0xCC, 0xF0, 0x00, 0xC0, 0x7F,
-       0x8C, 0x7E, 0x08, 0x12, 0x2E, 0xA2, 0x90, 0x85,
-       0xBB, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00, 0x14,
-       0x7F, 0x70, 0x7E, 0x0E, 0x12, 0x2E, 0xA2, 0x90,
-       0x81, 0xF9, 0x12, 0x20, 0xDA, 0x00, 0x00, 0x00,
-       0x00, 0xE4, 0xFD, 0xFF, 0x12, 0x55, 0x1C, 0x7F,
-       0x7C, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0xEC, 0x44,
-       0x80, 0xFC, 0x90, 0x82, 0x05, 0x12, 0x20, 0xCE,
-       0x90, 0x82, 0x05, 0x12, 0x44, 0xD9, 0x90, 0x85,
-       0xBB, 0x12, 0x20, 0xCE, 0x7F, 0x7C, 0x7E, 0x08,
-       0x12, 0x2E, 0xA2, 0x90, 0x01, 0x00, 0x74, 0x3F,
-       0xF0, 0xA3, 0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x05,
-       0x53, 0xE0, 0x44, 0x20, 0xF0, 0x22, 0x90, 0x01,
-       0x34, 0x74, 0x40, 0xF0, 0xFD, 0xE4, 0xFF, 0x74,
-       0x3D, 0x2F, 0xF8, 0xE6, 0x4D, 0xFE, 0xF6, 0x74,
-       0x30, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5,
-       0x83, 0xEE, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01,
-       0xC3, 0xC0, 0xD0, 0xE4, 0x90, 0x81, 0xCB, 0xF0,
-       0x12, 0x1F, 0xA4, 0xFF, 0x54, 0x01, 0xFE, 0x90,
-       0x81, 0x1F, 0xE0, 0x54, 0xFE, 0x4E, 0xFE, 0xF0,
-       0xEF, 0x54, 0x02, 0xFF, 0xEE, 0x54, 0xFD, 0x4F,
-       0xFF, 0xF0, 0x12, 0x1F, 0xA4, 0xFE, 0x54, 0x04,
-       0xFD, 0xEF, 0x54, 0xFB, 0x4D, 0xFF, 0x90, 0x81,
-       0x1F, 0xF0, 0xEE, 0x54, 0x08, 0xFE, 0xEF, 0x54,
-       0xF7, 0x4E, 0xFF, 0xF0, 0x12, 0x1F, 0xA4, 0xFE,
-       0x54, 0x10, 0xFD, 0xEF, 0x54, 0xEF, 0x4D, 0xFF,
-       0x90, 0x81, 0x1F, 0xF0, 0xEE, 0x54, 0x20, 0xFE,
-       0xEF, 0x54, 0xDF, 0x4E, 0xF0, 0x12, 0x1F, 0xA4,
-       0xC3, 0x13, 0x20, 0xE0, 0x02, 0x61, 0x5E, 0x90,
-       0x81, 0x1F, 0xE0, 0xFF, 0x30, 0xE0, 0x6D, 0x90,
-       0x81, 0xCB, 0x74, 0x21, 0xF0, 0xEF, 0x13, 0x13,
-       0x54, 0x3F, 0x30, 0xE0, 0x0B, 0x51, 0x4E, 0x90,
-       0x81, 0xCB, 0xE0, 0x44, 0x08, 0xF0, 0x80, 0x0C,
-       0xE4, 0x90, 0x81, 0x20, 0xF0, 0xA3, 0xF0, 0x7D,
-       0x40, 0xFF, 0x91, 0x26, 0x90, 0x81, 0x1F, 0xE0,
-       0xFD, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0,
-       0x07, 0x90, 0x81, 0xCB, 0xE0, 0x44, 0x12, 0xF0,
-       0xED, 0xC4, 0x54, 0x0F, 0x30, 0xE0, 0x07, 0x90,
-       0x81, 0xCB, 0xE0, 0x44, 0x14, 0xF0, 0x90, 0x81,
-       0x1F, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0x30, 0xE0,
-       0x07, 0x90, 0x81, 0xCB, 0xE0, 0x44, 0x80, 0xF0,
-       0x90, 0x81, 0xCB, 0xE0, 0x90, 0x05, 0x27, 0xF0,
-       0x90, 0x81, 0x22, 0xE0, 0x60, 0x02, 0x81, 0x17,
-       0x7F, 0x01, 0x80, 0x15, 0x90, 0x81, 0xCB, 0x74,
-       0x01, 0xF0, 0x90, 0x05, 0x27, 0xF0, 0x90, 0x81,
-       0x22, 0xE0, 0x64, 0x04, 0x60, 0x02, 0x81, 0x17,
-       0xFF, 0x12, 0x53, 0x0E, 0x81, 0x17, 0x90, 0x81,
-       0x1F, 0xE0, 0xFF, 0x20, 0xE0, 0x02, 0x61, 0xE7,
-       0x90, 0x81, 0xCB, 0x74, 0x31, 0xF0, 0xEF, 0x13,
-       0x13, 0x54, 0x3F, 0x30, 0xE0, 0x0B, 0x51, 0x4E,
-       0x90, 0x81, 0xCB, 0xE0, 0x44, 0x08, 0xF0, 0x80,
-       0x06, 0x7D, 0x40, 0xE4, 0xFF, 0x91, 0x26, 0x90,
-       0x81, 0x1F, 0xE0, 0xFD, 0x13, 0x13, 0x13, 0x54,
-       0x1F, 0x30, 0xE0, 0x07, 0x90, 0x81, 0xCB, 0xE0,
-       0x44, 0x02, 0xF0, 0xED, 0xC4, 0x54, 0x0F, 0x30,
-       0xE0, 0x07, 0x90, 0x81, 0xCB, 0xE0, 0x44, 0x04,
-       0xF0, 0x90, 0x81, 0xCB, 0xE0, 0x90, 0x05, 0x27,
-       0xF0, 0x90, 0x81, 0x23, 0xE0, 0x64, 0x02, 0x70,
-       0x1D, 0xFD, 0x7F, 0x04, 0x12, 0x47, 0x3D, 0x12,
-       0x51, 0x73, 0xBF, 0x01, 0x09, 0x90, 0x81, 0x29,
-       0xE0, 0xFF, 0x7D, 0x01, 0x80, 0x03, 0xE4, 0xFD,
-       0xFF, 0x12, 0x47, 0x3D, 0x80, 0x41, 0x90, 0x81,
-       0x2A, 0xE0, 0x90, 0x81, 0x23, 0xF0, 0x90, 0x05,
-       0x27, 0xE0, 0x44, 0x40, 0xF0, 0x80, 0x30, 0x90,
-       0x81, 0xCB, 0x74, 0x01, 0xF0, 0x90, 0x05, 0x27,
-       0xF0, 0x90, 0x81, 0x23, 0xE0, 0xB4, 0x02, 0x06,
-       0x7D, 0x01, 0x7F, 0x04, 0x80, 0x0B, 0x90, 0x81,
-       0x23, 0xE0, 0xB4, 0x08, 0x07, 0x7D, 0x01, 0x7F,
-       0x0C, 0x12, 0x47, 0x3D, 0xD1, 0x34, 0x90, 0x81,
-       0x29, 0x12, 0x47, 0x39, 0x12, 0x5A, 0xA7, 0xD0,
-       0xD0, 0x92, 0xAF, 0x22, 0x7D, 0x02, 0x7F, 0x02,
-       0x91, 0x26, 0x7D, 0x01, 0x7F, 0x02, 0x74, 0x3D,
-       0x2F, 0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E, 0xFE,
-       0xF6, 0x74, 0x30, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
-       0x01, 0xF5, 0x83, 0xEE, 0xF0, 0x22, 0xEF, 0x70,
-       0x37, 0x7D, 0x78, 0x7F, 0x02, 0x91, 0x26, 0x7D,
-       0x02, 0x7F, 0x03, 0x91, 0x26, 0x7D, 0xC8, 0x7F,
-       0x02, 0x12, 0x71, 0x8F, 0x90, 0x01, 0x57, 0xE4,
-       0xF0, 0x90, 0x01, 0x3C, 0x74, 0x02, 0xF0, 0x7D,
-       0x01, 0x7F, 0x0C, 0x12, 0x47, 0x3D, 0x90, 0x81,
-       0x24, 0xE0, 0x54, 0xF7, 0xF0, 0x54, 0xEF, 0xF0,
-       0x90, 0x06, 0x0A, 0xE0, 0x54, 0xF8, 0xF0, 0x22,
-       0x90, 0x01, 0x36, 0x74, 0x78, 0xF0, 0xA3, 0x74,
-       0x02, 0xF0, 0x7D, 0x78, 0xFF, 0x51, 0x57, 0x7D,
-       0x02, 0x7F, 0x03, 0x51, 0x57, 0x90, 0x06, 0x0A,
-       0xE0, 0x44, 0x07, 0xF0, 0x90, 0x81, 0x32, 0xA3,
-       0xE0, 0x90, 0x05, 0x58, 0xF0, 0x90, 0x80, 0xDE,
-       0xE0, 0xB4, 0x01, 0x15, 0x90, 0x81, 0x25, 0xE0,
-       0x54, 0xFB, 0xF0, 0x90, 0x81, 0x2A, 0xE0, 0x20,
-       0xE2, 0x0E, 0x7D, 0x01, 0x7F, 0x04, 0x02, 0x47,
-       0x3D, 0x90, 0x81, 0x25, 0xE0, 0x44, 0x04, 0xF0,
-       0x22, 0x90, 0x81, 0x1F, 0xE0, 0xFF, 0x30, 0xE0,
-       0x08, 0x90, 0x81, 0x23, 0xE0, 0x64, 0x02, 0x60,
-       0x3A, 0x90, 0x81, 0x27, 0xE0, 0x70, 0x04, 0xEF,
-       0x30, 0xE0, 0x0A, 0x90, 0x81, 0x2A, 0xE0, 0x64,
-       0x02, 0x60, 0x28, 0xB1, 0x83, 0x90, 0x81, 0x25,
-       0xE0, 0x13, 0x13, 0x13, 0x54, 0x1F, 0x30, 0xE0,
-       0x14, 0x90, 0x81, 0x2D, 0xE0, 0xFF, 0xA3, 0xE0,
-       0x6F, 0x70, 0x0A, 0xF1, 0xCD, 0x91, 0x1C, 0x90,
-       0x81, 0x2E, 0xE0, 0x14, 0xF0, 0x90, 0x01, 0xE6,
-       0xE0, 0x04, 0xF0, 0x22, 0x90, 0x81, 0x1F, 0xE0,
-       0x30, 0xE0, 0x06, 0x90, 0x81, 0x21, 0x74, 0x01,
-       0xF0, 0x90, 0x81, 0x27, 0xE0, 0x60, 0x45, 0x90,
-       0x81, 0x25, 0xE0, 0xFF, 0x13, 0x13, 0x13, 0x54,
-       0x1F, 0x30, 0xE0, 0x12, 0x90, 0x01, 0x3B, 0xE0,
-       0x30, 0xE4, 0x0B, 0x91, 0x1C, 0x90, 0x81, 0x2D,
-       0xE0, 0x14, 0x90, 0x05, 0x73, 0xF0, 0x90, 0x82,
-       0x0B, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x44, 0xA9,
-       0xC3, 0x90, 0x82, 0x0C, 0xE0, 0x94, 0x80, 0x90,
-       0x82, 0x0B, 0xE0, 0x64, 0x80, 0x94, 0x80, 0x40,
-       0x0B, 0x90, 0x01, 0x98, 0xE0, 0x54, 0xFE, 0xF0,
-       0xE0, 0x44, 0x01, 0xF0, 0x12, 0x75, 0xF8, 0xD1,
-       0xD6, 0x90, 0x81, 0x3F, 0xE0, 0x30, 0xE0, 0x0C,
-       0xE4, 0xF5, 0x1D, 0xA3, 0xF1, 0xFB, 0x90, 0x01,
-       0x57, 0x74, 0x05, 0xF0, 0x90, 0x01, 0xBE, 0xE0,
-       0x04, 0xF0, 0x22, 0x90, 0x80, 0xDE, 0xE0, 0x64,
-       0x01, 0x60, 0x02, 0xC1, 0x23, 0x90, 0x81, 0x27,
-       0xE0, 0x70, 0x02, 0xC1, 0x23, 0x90, 0x81, 0x26,
-       0xE0, 0xC4, 0x54, 0x0F, 0x64, 0x01, 0x70, 0x22,
-       0x90, 0x06, 0xAB, 0xE0, 0x90, 0x81, 0x2E, 0xF0,
-       0x90, 0x06, 0xAA, 0xE0, 0x90, 0x81, 0x2D, 0xF0,
-       0xA3, 0xE0, 0xFF, 0x70, 0x08, 0x90, 0x81, 0x2D,
-       0xE0, 0xFE, 0xFF, 0x80, 0x00, 0x90, 0x81, 0x2E,
-       0xEF, 0xF0, 0x90, 0x81, 0x25, 0xE0, 0x44, 0x04,
-       0xF0, 0xE4, 0x90, 0x81, 0x30, 0xF0, 0x90, 0x81,
-       0x32, 0xA3, 0xE0, 0x90, 0x05, 0x58, 0xF0, 0x90,
-       0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74,
-       0x02, 0xF0, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFD,
-       0xF0, 0x54, 0xEF, 0xF0, 0x90, 0x81, 0x26, 0xE0,
-       0xFF, 0xC4, 0x54, 0x0F, 0x24, 0xFD, 0x50, 0x02,
-       0x80, 0x0F, 0x90, 0x81, 0x1F, 0xE0, 0x30, 0xE0,
-       0x05, 0x12, 0x6D, 0xF2, 0x80, 0x03, 0x12, 0x6E,
-       0xC9, 0x90, 0x81, 0x25, 0xE0, 0x13, 0x13, 0x13,
-       0x54, 0x1F, 0x30, 0xE0, 0x0E, 0x90, 0x81, 0x2D,
-       0xE0, 0xFF, 0xA3, 0xE0, 0xB5, 0x07, 0x04, 0xF1,
-       0xCD, 0x91, 0x22, 0x90, 0x81, 0x1F, 0xE0, 0xC3,
-       0x13, 0x20, 0xE0, 0x07, 0x90, 0x81, 0x25, 0xE0,
-       0x44, 0x04, 0xF0, 0x22, 0xD1, 0xAB, 0xEF, 0x70,
-       0x02, 0xD1, 0x3C, 0x22, 0x90, 0x81, 0x27, 0xE0,
-       0x64, 0x01, 0x70, 0x66, 0x90, 0x81, 0x26, 0xE0,
-       0x54, 0x0F, 0x60, 0x51, 0x90, 0x81, 0x2A, 0xE0,
-       0x70, 0x03, 0xFF, 0x31, 0x93, 0x90, 0x81, 0x2A,
-       0xE0, 0x64, 0x0C, 0x60, 0x03, 0x12, 0x66, 0x26,
-       0x90, 0x01, 0x5B, 0xE4, 0xF0, 0x90, 0x01, 0x3C,
-       0x74, 0x04, 0xF0, 0xD1, 0xAB, 0xEF, 0x64, 0x01,
-       0x60, 0x38, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x3A,
-       0xE0, 0xC3, 0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4,
-       0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0x12, 0x50,
-       0x05, 0x90, 0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90,
-       0x06, 0x92, 0x74, 0x01, 0xF0, 0x90, 0x81, 0x24,
-       0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x81, 0x2A,
-       0xE0, 0x70, 0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12,
-       0x47, 0x3D, 0x22, 0x90, 0x04, 0x1A, 0xE0, 0xF4,
-       0x60, 0x03, 0x7F, 0x00, 0x22, 0x90, 0x04, 0x1B,
-       0xE0, 0x54, 0x07, 0x64, 0x07, 0x7F, 0x01, 0x60,
-       0x02, 0x7F, 0x00, 0x22, 0x12, 0x50, 0x60, 0x90,
-       0x81, 0x2D, 0xE0, 0x14, 0x90, 0x05, 0x73, 0xF0,
-       0x7D, 0x02, 0x7F, 0x02, 0x51, 0x57, 0x90, 0x81,
-       0x42, 0xE0, 0x30, 0xE0, 0x2D, 0x90, 0x80, 0xDE,
-       0xE0, 0xB4, 0x01, 0x26, 0x90, 0x82, 0x17, 0xE0,
-       0x04, 0xF0, 0xE0, 0xB4, 0x0A, 0x0B, 0x90, 0x81,
-       0x44, 0xE0, 0x04, 0xF0, 0xE4, 0x90, 0x82, 0x17,
-       0xF0, 0x90, 0x81, 0x44, 0xE0, 0xFF, 0x90, 0x81,
-       0x43, 0xE0, 0xB5, 0x07, 0x05, 0xE4, 0xA3, 0xF0,
-       0xF1, 0x0B, 0x22, 0xE4, 0xFF, 0x8F, 0x53, 0x90,
-       0x04, 0x1D, 0xE0, 0x60, 0x19, 0x90, 0x05, 0x22,
-       0xE0, 0xF5, 0x56, 0x74, 0xFF, 0xF0, 0xF1, 0x3A,
-       0xBF, 0x01, 0x03, 0x12, 0x74, 0xFB, 0x90, 0x05,
-       0x22, 0xE5, 0x56, 0xF0, 0x80, 0x03, 0x12, 0x74,
-       0xFB, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0, 0x7F,
-       0x01, 0x22, 0xE4, 0x90, 0x82, 0x0F, 0xF0, 0xA3,
-       0xF0, 0x90, 0x05, 0xF8, 0xE0, 0x70, 0x0F, 0xA3,
-       0xE0, 0x70, 0x0B, 0xA3, 0xE0, 0x70, 0x07, 0xA3,
-       0xE0, 0x70, 0x03, 0x7F, 0x01, 0x22, 0xD3, 0x90,
-       0x82, 0x10, 0xE0, 0x94, 0xE8, 0x90, 0x82, 0x0F,
-       0xE0, 0x94, 0x03, 0x40, 0x0A, 0x90, 0x01, 0xC0,
-       0xE0, 0x44, 0x20, 0xF0, 0x7F, 0x00, 0x22, 0x7F,
-       0x32, 0x7E, 0x00, 0x12, 0x32, 0xAA, 0x90, 0x82,
-       0x0F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x44, 0xA9,
-       0x80, 0xBF, 0x74, 0x1F, 0x2D, 0xF5, 0x82, 0xE4,
-       0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0x3F, 0xF0,
-       0xEF, 0x60, 0x1D, 0x74, 0x21, 0x2D, 0xF5, 0x82,
-       0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x10,
-       0xF0, 0x74, 0x1F, 0x2D, 0xF5, 0x82, 0xE4, 0x34,
-       0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0x22,
-       0x74, 0x21, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC,
-       0xF5, 0x83, 0xE0, 0x54, 0xEF, 0xF0, 0x74, 0x1F,
-       0x2D, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
-       0xE0, 0x44, 0x40, 0xF0, 0x22, 0xEF, 0x14, 0x90,
-       0x05, 0x73, 0xF0, 0x90, 0x01, 0x3F, 0x74, 0x10,
-       0xF0, 0xFD, 0x7F, 0x03, 0x74, 0x45, 0x2F, 0xF8,
-       0xE6, 0x4D, 0xFE, 0xF6, 0x74, 0x38, 0x2F, 0xF5,
-       0x82, 0xE4, 0x34, 0x01, 0xF5, 0x83, 0xEE, 0xF0,
-       0x22, 0xE0, 0x44, 0x02, 0xF0, 0xE4, 0xF5, 0x1D,
-       0x90, 0x81, 0x39, 0xE0, 0xF5, 0x1E, 0xE4, 0xFB,
-       0xFD, 0x7F, 0x54, 0x7E, 0x01, 0x8E, 0x19, 0x8F,
-       0x1A, 0xE5, 0x1E, 0x54, 0x07, 0xC4, 0x33, 0x54,
-       0xE0, 0x85, 0x19, 0x83, 0x85, 0x1A, 0x82, 0xF0,
-       0xE5, 0x1D, 0x54, 0x07, 0xC4, 0x33, 0x54, 0xE0,
-       0xFF, 0xE5, 0x1E, 0x13, 0x13, 0x13, 0x54, 0x1F,
-       0x4F, 0xA3, 0xF0, 0xEB, 0x54, 0x07, 0xC4, 0x33,
-       0x54, 0xE0, 0xFF, 0xE5, 0x1D, 0x13, 0x13, 0x13,
-       0x54, 0x1F, 0x4F, 0x85, 0x1A, 0x82, 0x85, 0x19,
-       0x83, 0xA3, 0xA3, 0xF0, 0xBD, 0x01, 0x0C, 0x85,
-       0x1A, 0x82, 0x8E, 0x83, 0xA3, 0xA3, 0xA3, 0x74,
-       0x03, 0xF0, 0x22, 0x85, 0x1A, 0x82, 0x85, 0x19,
-       0x83, 0xA3, 0xA3, 0xA3, 0x74, 0x01, 0xF0, 0x22,
-       0xE4, 0x90, 0x81, 0x4D, 0xF0, 0x90, 0x81, 0x27,
-       0xE0, 0x60, 0x58, 0x90, 0x80, 0xDE, 0xE0, 0x64,
-       0x01, 0x70, 0x50, 0x90, 0x81, 0x4D, 0x04, 0xF0,
-       0xE4, 0x90, 0x81, 0x2E, 0xF0, 0x90, 0x81, 0x1F,
-       0xE0, 0x30, 0xE0, 0x15, 0x90, 0x81, 0x23, 0xE0,
-       0xB4, 0x02, 0x05, 0xE4, 0x90, 0x81, 0x4D, 0xF0,
-       0x31, 0x73, 0xEF, 0x70, 0x04, 0x90, 0x81, 0x4D,
-       0xF0, 0x90, 0x81, 0x4D, 0xE0, 0x60, 0x24, 0x90,
-       0x81, 0x2B, 0xE0, 0x44, 0x10, 0xF0, 0xE4, 0xF5,
-       0x1D, 0x90, 0x81, 0x2F, 0x12, 0x4F, 0xFB, 0x90,
-       0x01, 0x57, 0x74, 0x05, 0xF0, 0x90, 0x81, 0x2A,
-       0xE0, 0x20, 0xE2, 0x07, 0x7D, 0x01, 0x7F, 0x04,
-       0x12, 0x47, 0x3D, 0x22, 0xE4, 0x90, 0x81, 0x4C,
-       0xF0, 0x90, 0x81, 0x27, 0xE0, 0x70, 0x02, 0x21,
-       0x72, 0x90, 0x80, 0xDE, 0xE0, 0x64, 0x01, 0x60,
-       0x02, 0x21, 0x72, 0x90, 0x81, 0x26, 0xE0, 0xFF,
-       0xC4, 0x54, 0x0F, 0x60, 0x22, 0x24, 0xFE, 0x60,
-       0x03, 0x04, 0x70, 0x21, 0x90, 0x81, 0x2E, 0xE0,
-       0x14, 0xF0, 0xE0, 0xFF, 0x60, 0x06, 0x90, 0x81,
-       0x30, 0xE0, 0x60, 0x11, 0xEF, 0x70, 0x08, 0x90,
-       0x81, 0x2D, 0xE0, 0xA3, 0xF0, 0x80, 0x00, 0x90,
-       0x81, 0x4C, 0x74, 0x01, 0xF0, 0x90, 0x81, 0x1F,
-       0xE0, 0x30, 0xE0, 0x15, 0x90, 0x81, 0x23, 0xE0,
-       0xB4, 0x02, 0x05, 0xE4, 0x90, 0x81, 0x4C, 0xF0,
-       0x31, 0x73, 0xEF, 0x70, 0x04, 0x90, 0x81, 0x4C,
-       0xF0, 0x90, 0x81, 0x4C, 0xE0, 0x60, 0x43, 0x90,
-       0x81, 0x2B, 0xE0, 0x44, 0x10, 0xF0, 0x90, 0x81,
-       0x30, 0xE0, 0x60, 0x03, 0xB4, 0x01, 0x09, 0xE4,
-       0xF5, 0x1D, 0x90, 0x81, 0x30, 0xE0, 0x80, 0x0D,
-       0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x30, 0xE0, 0x75,
-       0xF0, 0x03, 0xA4, 0x24, 0xFE, 0xFF, 0x90, 0x81,
-       0x2F, 0xE0, 0x2F, 0x12, 0x4F, 0xFC, 0x90, 0x01,
-       0x57, 0x74, 0x05, 0xF0, 0x90, 0x81, 0x2A, 0xE0,
-       0x20, 0xE2, 0x07, 0x7D, 0x01, 0x7F, 0x04, 0x12,
-       0x47, 0x3D, 0x22, 0x90, 0x05, 0x43, 0xE0, 0x7F,
-       0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0x22, 0x90,
-       0x81, 0x27, 0xE0, 0x70, 0x07, 0x90, 0x81, 0x1F,
-       0xE0, 0x30, 0xE0, 0x11, 0x90, 0x81, 0x1F, 0xE0,
-       0x30, 0xE0, 0x07, 0x31, 0x73, 0xBF, 0x01, 0x05,
-       0x41, 0x5B, 0x12, 0x4E, 0x3C, 0x22, 0xD3, 0x10,
-       0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81, 0x1E,
-       0xE0, 0xB4, 0x01, 0x04, 0x7F, 0x04, 0x80, 0x0B,
-       0x31, 0x73, 0xBF, 0x01, 0x04, 0x7F, 0x01, 0x80,
-       0x02, 0x7F, 0x02, 0x71, 0x0E, 0xD0, 0xD0, 0x92,
-       0xAF, 0x22, 0x90, 0x81, 0x4B, 0xE0, 0x60, 0x0F,
-       0xE4, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x02,
-       0xF0, 0x90, 0x05, 0xFC, 0xE0, 0x04, 0xF0, 0x90,
-       0x81, 0x1F, 0xE0, 0x30, 0xE0, 0x10, 0xA3, 0x74,
-       0x01, 0xF0, 0x90, 0x81, 0x1F, 0xE0, 0xFF, 0xC3,
-       0x13, 0x30, 0xE0, 0x02, 0x31, 0x9E, 0x11, 0xC4,
-       0x90, 0x81, 0x3F, 0xE0, 0x30, 0xE0, 0x07, 0x91,
-       0x65, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x22, 0x90,
-       0x81, 0x1F, 0xE0, 0xFF, 0x30, 0xE0, 0x3D, 0x90,
-       0x81, 0x23, 0xE0, 0x7E, 0x00, 0xB4, 0x02, 0x02,
-       0x7E, 0x01, 0x90, 0x81, 0x22, 0xE0, 0x7D, 0x00,
-       0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E, 0x70,
-       0x23, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x02, 0x21,
-       0x9E, 0x51, 0x45, 0x90, 0x81, 0x23, 0xE0, 0xB4,
-       0x08, 0x06, 0xE4, 0xFD, 0x7F, 0x0C, 0x80, 0x09,
-       0x90, 0x81, 0x23, 0xE0, 0x70, 0x06, 0xFD, 0x7F,
-       0x04, 0x12, 0x47, 0x3D, 0x22, 0x90, 0x81, 0x1E,
-       0xE0, 0xB4, 0x01, 0x0F, 0x90, 0x81, 0x23, 0xE0,
-       0x64, 0x02, 0x60, 0x07, 0x7D, 0x01, 0x7F, 0x02,
-       0x12, 0x47, 0x3D, 0x90, 0x81, 0x27, 0xE0, 0x64,
-       0x02, 0x60, 0x14, 0x90, 0x81, 0x26, 0xE0, 0x54,
-       0x0F, 0x60, 0x0C, 0x12, 0x4E, 0xAB, 0xEF, 0x70,
-       0x06, 0xFD, 0x7F, 0x0C, 0x12, 0x47, 0x3D, 0x22,
-       0x90, 0x81, 0x1F, 0xE0, 0xFF, 0x30, 0xE0, 0x3F,
-       0x90, 0x81, 0x23, 0xE0, 0x7E, 0x00, 0xB4, 0x02,
-       0x02, 0x7E, 0x01, 0x90, 0x81, 0x22, 0xE0, 0x7D,
-       0x00, 0xB4, 0x04, 0x02, 0x7D, 0x01, 0xED, 0x4E,
-       0x70, 0x25, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x02,
-       0x21, 0x9E, 0x12, 0x74, 0xAC, 0x90, 0x81, 0x23,
-       0xE0, 0xB4, 0x0C, 0x06, 0xE4, 0xFD, 0x7F, 0x08,
-       0x80, 0x0A, 0x90, 0x81, 0x23, 0xE0, 0xB4, 0x04,
-       0x06, 0xE4, 0xFD, 0xFF, 0x12, 0x47, 0x3D, 0x22,
-       0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
-       0x81, 0xCB, 0x12, 0x45, 0x1F, 0x12, 0x1F, 0xA4,
-       0xFF, 0x90, 0x81, 0x1E, 0xF0, 0xBF, 0x01, 0x12,
-       0x90, 0x81, 0xCB, 0x12, 0x45, 0x16, 0x90, 0x00,
-       0x01, 0x12, 0x1F, 0xBD, 0x64, 0x01, 0x60, 0x21,
-       0x80, 0x1D, 0x90, 0x81, 0xCB, 0x12, 0x45, 0x16,
-       0x90, 0x00, 0x01, 0x12, 0x1F, 0xBD, 0x64, 0x01,
-       0x60, 0x0F, 0x90, 0x81, 0x1F, 0xE0, 0x20, 0xE0,
-       0x06, 0xE4, 0xFF, 0x71, 0x0E, 0x80, 0x02, 0x31,
-       0x9E, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
-       0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81, 0x22,
-       0xE0, 0x90, 0x82, 0x16, 0xF0, 0x6F, 0x70, 0x02,
-       0x81, 0x04, 0xEF, 0x14, 0x60, 0x3E, 0x14, 0x60,
-       0x62, 0x14, 0x70, 0x02, 0x61, 0xB8, 0x14, 0x70,
-       0x02, 0x61, 0xDF, 0x24, 0x04, 0x60, 0x02, 0x81,
-       0x04, 0x90, 0x82, 0x16, 0xE0, 0xFF, 0xB4, 0x04,
-       0x04, 0x91, 0x41, 0x81, 0x04, 0xEF, 0xB4, 0x02,
-       0x04, 0x91, 0x50, 0x81, 0x04, 0x90, 0x82, 0x16,
-       0xE0, 0xFF, 0xB4, 0x03, 0x04, 0x91, 0x54, 0x81,
-       0x04, 0xEF, 0x64, 0x01, 0x60, 0x02, 0x81, 0x04,
-       0x91, 0x43, 0x81, 0x04, 0x90, 0x82, 0x16, 0xE0,
-       0xFF, 0xB4, 0x04, 0x04, 0x91, 0xF3, 0x81, 0x04,
-       0xEF, 0xB4, 0x02, 0x04, 0x91, 0x58, 0x81, 0x04,
-       0x90, 0x82, 0x16, 0xE0, 0xFF, 0xB4, 0x03, 0x04,
-       0x91, 0xE8, 0x81, 0x04, 0xEF, 0x70, 0x7D, 0x91,
-       0x2B, 0x80, 0x79, 0x90, 0x82, 0x16, 0xE0, 0xB4,
-       0x04, 0x05, 0x12, 0x74, 0x60, 0x80, 0x6D, 0x90,
-       0x82, 0x16, 0xE0, 0xB4, 0x01, 0x04, 0x91, 0x21,
-       0x80, 0x62, 0x90, 0x82, 0x16, 0xE0, 0xB4, 0x03,
-       0x05, 0x12, 0x74, 0x71, 0x80, 0x56, 0x90, 0x82,
-       0x16, 0xE0, 0x70, 0x50, 0x91, 0x1F, 0x80, 0x4C,
-       0x90, 0x82, 0x16, 0xE0, 0xFF, 0xB4, 0x04, 0x05,
-       0x12, 0x74, 0x4C, 0x80, 0x3F, 0xEF, 0xB4, 0x01,
-       0x04, 0x91, 0x34, 0x80, 0x37, 0xEF, 0xB4, 0x02,
-       0x04, 0x91, 0xDF, 0x80, 0x2F, 0x90, 0x82, 0x16,
-       0xE0, 0x70, 0x29, 0x91, 0x32, 0x80, 0x25, 0x90,
-       0x82, 0x16, 0xE0, 0xFF, 0xB4, 0x03, 0x05, 0x12,
-       0x74, 0x7B, 0x80, 0x18, 0xEF, 0xB4, 0x01, 0x04,
-       0x91, 0x0B, 0x80, 0x10, 0xEF, 0xB4, 0x02, 0x04,
-       0xB1, 0x06, 0x80, 0x08, 0x90, 0x82, 0x16, 0xE0,
-       0x70, 0x02, 0x91, 0x09, 0xD0, 0xD0, 0x92, 0xAF,
-       0x22, 0x91, 0x2B, 0x90, 0x05, 0x22, 0x74, 0x6F,
-       0xF0, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0,
-       0x90, 0x81, 0x22, 0x74, 0x04, 0xF0, 0x22, 0x91,
-       0x2B, 0x12, 0x49, 0xDD, 0x90, 0x81, 0x22, 0x74,
-       0x02, 0xF0, 0x22, 0x90, 0x81, 0x22, 0x74, 0x01,
-       0xF0, 0x22, 0x91, 0x2B, 0x90, 0x05, 0x22, 0x74,
-       0xFF, 0xF0, 0x90, 0x81, 0x22, 0x74, 0x03, 0xF0,
-       0x22, 0x91, 0xF3, 0x90, 0x05, 0x27, 0xE0, 0x54,
-       0xBF, 0xF0, 0xE4, 0x90, 0x81, 0x22, 0xF0, 0x22,
-       0x91, 0x58, 0x80, 0xEF, 0x91, 0xE8, 0x80, 0xEB,
-       0x91, 0x65, 0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90,
-       0x81, 0x22, 0x04, 0xF0, 0x22, 0xD3, 0x10, 0xAF,
-       0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x01, 0x01, 0xE0,
-       0x44, 0x02, 0xF0, 0x90, 0x01, 0x00, 0x74, 0xFF,
-       0xF0, 0x90, 0x06, 0xB7, 0x74, 0x09, 0xF0, 0x90,
-       0x06, 0xB4, 0x74, 0x86, 0xF0, 0x7F, 0x7C, 0x7E,
-       0x08, 0x12, 0x2D, 0x5C, 0xEC, 0x54, 0x7F, 0xFC,
-       0x90, 0x82, 0x01, 0x12, 0x20, 0xCE, 0x90, 0x82,
-       0x01, 0x12, 0x44, 0xD9, 0x90, 0x85, 0xBB, 0x12,
-       0x20, 0xCE, 0x7F, 0x7C, 0x7E, 0x08, 0x12, 0x2E,
-       0xA2, 0x90, 0x85, 0xBB, 0x12, 0x20, 0xDA, 0xCC,
-       0xC0, 0x00, 0xC0, 0x7F, 0x8C, 0x7E, 0x08, 0x12,
-       0x2E, 0xA2, 0x90, 0x85, 0xBB, 0x12, 0x20, 0xDA,
-       0x00, 0xC0, 0x00, 0x14, 0x7F, 0x70, 0x7E, 0x0E,
-       0x12, 0x2E, 0xA2, 0x90, 0x81, 0xF9, 0x12, 0x20,
-       0xDA, 0x00, 0x03, 0x3E, 0x60, 0xE4, 0xFD, 0xFF,
-       0xB1, 0x1C, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x91,
-       0x65, 0x90, 0x81, 0x22, 0x74, 0x03, 0xF0, 0x22,
-       0x90, 0x05, 0x22, 0xE4, 0xF0, 0x90, 0x81, 0x22,
-       0x04, 0xF0, 0x22, 0x90, 0x05, 0x22, 0xE4, 0xF0,
-       0x90, 0x05, 0x27, 0xE0, 0x44, 0x40, 0xF0, 0x90,
-       0x81, 0x22, 0x74, 0x01, 0xF0, 0x22, 0x91, 0x65,
-       0x90, 0x05, 0x22, 0x74, 0x6F, 0xF0, 0x90, 0x05,
-       0x27, 0xE0, 0x54, 0xBF, 0xF0, 0x90, 0x81, 0x22,
-       0x74, 0x04, 0xF0, 0x22, 0xD3, 0x10, 0xAF, 0x01,
-       0xC3, 0xC0, 0xD0, 0xC0, 0x07, 0xC0, 0x05, 0x90,
-       0x81, 0xF9, 0x12, 0x44, 0xD9, 0x90, 0x81, 0xE5,
-       0x12, 0x20, 0xCE, 0xD0, 0x05, 0xD0, 0x07, 0x12,
-       0x60, 0xF5, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90,
-       0x81, 0xC8, 0x12, 0x45, 0x1F, 0xEF, 0x12, 0x45,
-       0x28, 0x55, 0x71, 0x00, 0x55, 0x7A, 0x01, 0x55,
-       0x83, 0x02, 0x55, 0x8B, 0x03, 0x55, 0x94, 0x04,
-       0x55, 0x9C, 0x20, 0x55, 0xA4, 0x21, 0x55, 0xAD,
-       0x23, 0x55, 0xB5, 0x24, 0x55, 0xBE, 0x25, 0x55,
-       0xC7, 0x26, 0x55, 0xCF, 0xC0, 0x00, 0x00, 0x55,
-       0xD8, 0x90, 0x81, 0xC8, 0x12, 0x45, 0x16, 0x02,
-       0x6A, 0xB0, 0x90, 0x81, 0xC8, 0x12, 0x45, 0x16,
-       0x02, 0x65, 0x81, 0x90, 0x81, 0xC8, 0x12, 0x45,
-       0x16, 0x41, 0xC0, 0x90, 0x81, 0xC8, 0x12, 0x45,
-       0x16, 0x02, 0x75, 0xD8, 0x90, 0x81, 0xC8, 0x12,
-       0x45, 0x16, 0x80, 0x44, 0x90, 0x81, 0xC8, 0x12,
-       0x45, 0x16, 0xC1, 0x4B, 0x90, 0x81, 0xC8, 0x12,
-       0x45, 0x16, 0x02, 0x6A, 0xF8, 0x90, 0x81, 0xC8,
-       0x12, 0x45, 0x16, 0xE1, 0xE1, 0x90, 0x81, 0xC8,
-       0x12, 0x45, 0x16, 0x02, 0x4A, 0x6C, 0x90, 0x81,
-       0xC8, 0x12, 0x45, 0x16, 0x02, 0x6B, 0x3E, 0x90,
-       0x81, 0xC8, 0x12, 0x45, 0x16, 0x80, 0x3E, 0x90,
-       0x81, 0xC8, 0x12, 0x45, 0x16, 0x02, 0x6B, 0x4E,
-       0x90, 0x01, 0xC0, 0xE0, 0x44, 0x01, 0xF0, 0x22,
-       0x12, 0x5A, 0x4B, 0x12, 0x1F, 0xA4, 0xFF, 0x54,
-       0x01, 0xFE, 0x90, 0x81, 0x45, 0xE0, 0x54, 0xFE,
-       0x4E, 0xF0, 0xEF, 0xC3, 0x13, 0x30, 0xE0, 0x14,
-       0x90, 0x00, 0x01, 0x12, 0x1F, 0xBD, 0x90, 0x81,
-       0x46, 0xF0, 0x90, 0x00, 0x02, 0x12, 0x1F, 0xBD,
-       0x90, 0x81, 0x47, 0xF0, 0x22, 0x12, 0x1F, 0xA4,
-       0xFF, 0x54, 0x01, 0xFE, 0x90, 0x81, 0x3F, 0xE0,
-       0x54, 0xFE, 0x4E, 0xF0, 0x90, 0x00, 0x01, 0x12,
-       0x1F, 0xBD, 0xFE, 0x90, 0x05, 0x54, 0xE0, 0xC3,
-       0x9E, 0x90, 0x81, 0x40, 0xF0, 0xEF, 0x20, 0xE0,
-       0x07, 0x91, 0x65, 0x90, 0x05, 0x22, 0xE4, 0xF0,
-       0x90, 0x81, 0x3F, 0xE0, 0x54, 0x01, 0x90, 0x01,
-       0xBC, 0xF0, 0x90, 0x81, 0x40, 0xE0, 0x90, 0x01,
-       0xBD, 0xF0, 0x22, 0x12, 0x1F, 0xA4, 0xFF, 0x54,
-       0x7F, 0x90, 0x81, 0x27, 0xF0, 0xEF, 0xC4, 0x13,
-       0x13, 0x13, 0x54, 0x01, 0xA3, 0xF0, 0x90, 0x00,
-       0x01, 0x12, 0x1F, 0xBD, 0xFF, 0x54, 0xF0, 0xC4,
-       0x54, 0x0F, 0xFE, 0x90, 0x81, 0x26, 0xE0, 0x54,
-       0xF0, 0x4E, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x1F,
-       0xBD, 0x54, 0x01, 0x25, 0xE0, 0xFE, 0x90, 0x81,
-       0x24, 0xE0, 0x54, 0xFD, 0x4E, 0xF0, 0xEF, 0x54,
-       0x0F, 0xC4, 0x54, 0xF0, 0xFF, 0x90, 0x81, 0x26,
-       0xE0, 0x54, 0x0F, 0x4F, 0xF0, 0x90, 0x00, 0x04,
-       0x12, 0x1F, 0xBD, 0x90, 0x81, 0x29, 0xF0, 0xD1,
-       0xC6, 0x90, 0x01, 0xB9, 0x74, 0x01, 0xF0, 0x90,
-       0x01, 0xB8, 0xF0, 0x90, 0x81, 0x27, 0xE0, 0x90,
-       0x01, 0xBA, 0xF0, 0x90, 0x81, 0x29, 0xE0, 0x90,
-       0x01, 0xBB, 0xF0, 0x90, 0x81, 0x26, 0xE0, 0x54,
-       0x0F, 0x90, 0x01, 0xBE, 0xF0, 0x22, 0x90, 0x81,
-       0xCB, 0x12, 0x45, 0x1F, 0x12, 0x72, 0xB3, 0x90,
-       0x81, 0x27, 0xE0, 0xFF, 0x12, 0x4C, 0x3E, 0x90,
-       0x81, 0x27, 0xE0, 0x60, 0x19, 0x90, 0x81, 0xCB,
-       0x12, 0x45, 0x16, 0x90, 0x00, 0x01, 0x12, 0x1F,
-       0xBD, 0x54, 0x0F, 0xFF, 0x90, 0x00, 0x02, 0x12,
-       0x1F, 0xBD, 0xFD, 0x12, 0x72, 0xC4, 0x22, 0xC0,
-       0xE0, 0xC0, 0xF0, 0xC0, 0x83, 0xC0, 0x82, 0xC0,
-       0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x00, 0xC0, 0x01,
-       0xC0, 0x02, 0xC0, 0x03, 0xC0, 0x04, 0xC0, 0x05,
-       0xC0, 0x06, 0xC0, 0x07, 0x90, 0x01, 0xC4, 0x74,
-       0xF7, 0xF0, 0x74, 0x56, 0xA3, 0xF0, 0x12, 0x6C,
-       0xA5, 0xE5, 0x49, 0x30, 0xE1, 0x03, 0x12, 0x6F,
-       0x79, 0xE5, 0x49, 0x30, 0xE2, 0x02, 0xF1, 0xA5,
-       0xE5, 0x49, 0x30, 0xE3, 0x03, 0x12, 0x6F, 0x8D,
-       0xE5, 0x4A, 0x30, 0xE0, 0x03, 0x12, 0x6F, 0xC9,
-       0xE5, 0x4A, 0x30, 0xE4, 0x03, 0x12, 0x70, 0x22,
-       0xE5, 0x4B, 0x30, 0xE1, 0x02, 0x51, 0x78, 0xE5,
-       0x4B, 0x30, 0xE0, 0x02, 0x31, 0xFF, 0xE5, 0x4B,
-       0x30, 0xE3, 0x02, 0xF1, 0xE0, 0xE5, 0x4C, 0x30,
-       0xE1, 0x05, 0x7F, 0x03, 0x12, 0x44, 0x27, 0xE5,
-       0x4C, 0x30, 0xE4, 0x03, 0x12, 0x4E, 0xC4, 0xE5,
-       0x4C, 0x30, 0xE5, 0x03, 0x12, 0x70, 0x38, 0xE5,
-       0x4C, 0x30, 0xE6, 0x03, 0x12, 0x70, 0xCE, 0x74,
-       0xF7, 0x04, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x56,
-       0xA3, 0xF0, 0xD0, 0x07, 0xD0, 0x06, 0xD0, 0x05,
-       0xD0, 0x04, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01,
-       0xD0, 0x00, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83,
-       0xD0, 0xF0, 0xD0, 0xE0, 0x32, 0x90, 0x81, 0x27,
-       0xE0, 0x60, 0x34, 0x90, 0x06, 0x92, 0xE0, 0x30,
-       0xE0, 0x23, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x3A,
-       0xE0, 0xC3, 0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4,
-       0xFB, 0xFD, 0x7F, 0x58, 0x7E, 0x01, 0x11, 0x05,
-       0x90, 0x01, 0x5B, 0x74, 0x05, 0xF0, 0x90, 0x06,
-       0x92, 0x74, 0x01, 0xF0, 0x22, 0x90, 0x81, 0x24,
-       0xE0, 0x54, 0xF7, 0xF0, 0x12, 0x47, 0x2A, 0x22,
-       0x22, 0x12, 0x1F, 0xA4, 0x90, 0x81, 0x31, 0xF0,
-       0x22, 0x90, 0x01, 0xC8, 0xE4, 0xF0, 0xA3, 0xF0,
-       0xA3, 0xF0, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0x51,
-       0x7F, 0xFF, 0xFE, 0x12, 0x2B, 0x27, 0xBF, 0x01,
-       0x09, 0x90, 0x81, 0x51, 0xE0, 0x64, 0x03, 0x60,
-       0x03, 0x22, 0x01, 0xAB, 0xE4, 0x90, 0x81, 0x56,
-       0xF0, 0x90, 0x81, 0x56, 0xE0, 0xFF, 0xC3, 0x94,
-       0x02, 0x40, 0x02, 0x01, 0xE6, 0xC3, 0x74, 0xFE,
-       0x9F, 0xFF, 0xE4, 0x94, 0x00, 0xFE, 0x7B, 0x01,
-       0x7A, 0x81, 0x79, 0x52, 0x12, 0x2B, 0x27, 0xEF,
-       0x64, 0x01, 0x70, 0x77, 0x90, 0x81, 0x52, 0xE0,
-       0xFF, 0x54, 0xC0, 0xFE, 0x60, 0x05, 0xEF, 0x54,
-       0x0C, 0x70, 0x16, 0x90, 0x81, 0x52, 0xE0, 0xFF,
-       0x54, 0x30, 0x60, 0x67, 0xEF, 0x54, 0x03, 0x60,
-       0x62, 0x90, 0x81, 0x53, 0x74, 0x01, 0xF0, 0x80,
-       0x05, 0xE4, 0x90, 0x81, 0x53, 0xF0, 0x90, 0x81,
-       0x53, 0xE0, 0x90, 0x81, 0x52, 0x70, 0x16, 0xE0,
-       0xFF, 0xEE, 0x13, 0x13, 0x54, 0x3F, 0x90, 0x81,
-       0x54, 0xF0, 0xEF, 0x54, 0x0C, 0x13, 0x13, 0x54,
-       0x3F, 0xA3, 0xF0, 0x80, 0x0D, 0xE0, 0xFE, 0x54,
-       0x30, 0x90, 0x81, 0x54, 0xF0, 0xEE, 0x54, 0x03,
-       0xA3, 0xF0, 0x90, 0x81, 0x54, 0xE0, 0x64, 0x30,
-       0x70, 0x54, 0xA3, 0xE0, 0x64, 0x02, 0x70, 0x4E,
-       0x90, 0x00, 0xF5, 0xE0, 0x54, 0x40, 0x90, 0x81,
-       0x57, 0xF0, 0xE0, 0x70, 0x41, 0xA3, 0x74, 0x02,
-       0xF0, 0x80, 0x10, 0x90, 0x81, 0x58, 0x74, 0x01,
-       0xF0, 0x80, 0x08, 0x90, 0x81, 0x56, 0xE0, 0x04,
-       0xF0, 0x01, 0x11, 0x90, 0x01, 0xC4, 0x74, 0xE9,
-       0xF0, 0x74, 0x57, 0xA3, 0xF0, 0x90, 0x81, 0x58,
-       0xE0, 0x90, 0x01, 0xC8, 0xF0, 0x90, 0x81, 0x52,
-       0xE0, 0x90, 0x01, 0xC9, 0xF0, 0x90, 0x81, 0x53,
-       0xE0, 0x90, 0x01, 0xCA, 0xF0, 0xE4, 0xFD, 0x7F,
-       0x1F, 0x12, 0x32, 0x1E, 0x80, 0xD5, 0x22, 0x90,
-       0x00, 0xF7, 0xE0, 0x20, 0xE7, 0x09, 0xE0, 0x7F,
-       0x01, 0x20, 0xE6, 0x0C, 0x7F, 0x02, 0x22, 0x90,
-       0x00, 0xF7, 0xE0, 0x30, 0xE6, 0x02, 0x7F, 0x03,
-       0x22, 0x11, 0xE7, 0x90, 0x80, 0x3C, 0xEF, 0xF0,
-       0x31, 0x13, 0x90, 0x01, 0x64, 0x74, 0x01, 0xF0,
-       0x02, 0x2D, 0xA7, 0x31, 0x81, 0x31, 0xB1, 0x31,
-       0x40, 0x31, 0x5F, 0xE4, 0xF5, 0x35, 0xF5, 0x36,
-       0xF5, 0x37, 0xF5, 0x38, 0xAD, 0x35, 0x7F, 0x50,
-       0x12, 0x32, 0x1E, 0xAD, 0x36, 0x7F, 0x51, 0x12,
-       0x32, 0x1E, 0xAD, 0x37, 0x7F, 0x52, 0x12, 0x32,
-       0x1E, 0xAD, 0x38, 0x7F, 0x53, 0x02, 0x32, 0x1E,
-       0x75, 0x3D, 0x10, 0xE4, 0xF5, 0x3E, 0x75, 0x3F,
-       0x07, 0x75, 0x40, 0x02, 0x90, 0x01, 0x30, 0xE5,
-       0x3D, 0xF0, 0xA3, 0xE5, 0x3E, 0xF0, 0xA3, 0xE5,
-       0x3F, 0xF0, 0xA3, 0xE5, 0x40, 0xF0, 0x22, 0x75,
-       0x45, 0x0E, 0x75, 0x46, 0x01, 0x43, 0x46, 0x10,
-       0x75, 0x47, 0x03, 0x75, 0x48, 0x62, 0x90, 0x01,
-       0x38, 0xE5, 0x45, 0xF0, 0xA3, 0xE5, 0x46, 0xF0,
-       0xA3, 0xE5, 0x47, 0xF0, 0xA3, 0xE5, 0x48, 0xF0,
-       0x22, 0x90, 0x01, 0x30, 0xE4, 0xF0, 0xA3, 0xF0,
-       0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x38, 0xF0,
-       0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xFD, 0x7F,
-       0x50, 0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x51,
-       0x12, 0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x52, 0x12,
-       0x32, 0x1E, 0xE4, 0xFD, 0x7F, 0x53, 0x02, 0x32,
-       0x1E, 0x90, 0x01, 0x34, 0x74, 0xFF, 0xF0, 0xA3,
-       0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x3C,
-       0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xFD,
-       0x7F, 0x54, 0x12, 0x32, 0x1E, 0x7D, 0xFF, 0x7F,
-       0x55, 0x12, 0x32, 0x1E, 0x7D, 0xFF, 0x7F, 0x56,
-       0x12, 0x32, 0x1E, 0x7D, 0xFF, 0x7F, 0x57, 0x02,
-       0x32, 0x1E, 0x90, 0x00, 0x80, 0xE0, 0x44, 0x80,
-       0xFD, 0x7F, 0x80, 0x12, 0x32, 0x1E, 0x90, 0xFD,
-       0x00, 0xE0, 0x54, 0xBF, 0xF0, 0x12, 0x57, 0xE9,
-       0x51, 0x77, 0x12, 0x32, 0x77, 0x51, 0xC9, 0x51,
-       0x5E, 0x7F, 0x01, 0x12, 0x43, 0x15, 0x90, 0x81,
-       0x41, 0x74, 0x02, 0xF0, 0xFF, 0x12, 0x43, 0x15,
-       0x90, 0x81, 0x41, 0xE0, 0x04, 0xF0, 0x7F, 0x03,
-       0x12, 0x43, 0x15, 0x90, 0x81, 0x41, 0xE0, 0x04,
-       0xF0, 0x31, 0x01, 0x51, 0x3F, 0x90, 0x00, 0x80,
-       0xE0, 0x44, 0x40, 0xFD, 0x7F, 0x80, 0x12, 0x32,
-       0x1E, 0x75, 0x20, 0xFF, 0x51, 0x68, 0x51, 0xF9,
-       0x51, 0x7F, 0xE4, 0xFF, 0x02, 0x43, 0x9E, 0x51,
-       0x62, 0x51, 0x6F, 0x51, 0xA7, 0x71, 0x4F, 0x51,
-       0x8A, 0x51, 0x95, 0x90, 0x81, 0x45, 0xE0, 0x54,
-       0xFE, 0xF0, 0xA3, 0x74, 0x03, 0xF0, 0xA3, 0xF0,
-       0xE4, 0xA3, 0xF0, 0xA3, 0xF0, 0x22, 0xE4, 0xF5,
-       0x4D, 0x22, 0xE4, 0x90, 0x80, 0xDE, 0xF0, 0x22,
-       0x75, 0xE8, 0x03, 0x75, 0xA8, 0x84, 0x22, 0xE4,
-       0x90, 0x80, 0xD8, 0xF0, 0xA3, 0xF0, 0x22, 0x90,
-       0x01, 0x94, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90,
-       0x01, 0xE4, 0x74, 0x0B, 0xF0, 0xA3, 0x74, 0x01,
-       0xF0, 0x22, 0x90, 0x81, 0x3F, 0xE0, 0x54, 0xFE,
-       0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0x90, 0x81, 0x42,
-       0xE0, 0x54, 0xFE, 0xF0, 0x54, 0x7F, 0xF0, 0xA3,
-       0x74, 0x0A, 0xF0, 0xE4, 0xA3, 0xF0, 0x22, 0x90,
-       0x81, 0x1F, 0xE0, 0x54, 0xFE, 0xF0, 0x54, 0xFD,
-       0xF0, 0x54, 0xFB, 0xF0, 0x54, 0xF7, 0xF0, 0x54,
-       0xEF, 0xF0, 0x54, 0xDF, 0xF0, 0xE4, 0xA3, 0xF0,
-       0xA3, 0xF0, 0xA3, 0xF0, 0xA3, 0x74, 0x0C, 0xF0,
-       0x22, 0x90, 0x01, 0x01, 0xE0, 0x44, 0x04, 0xF0,
-       0x90, 0x01, 0x9C, 0x74, 0x7E, 0xF0, 0xA3, 0x74,
-       0x92, 0xF0, 0xA3, 0x74, 0xA0, 0xF0, 0xA3, 0x74,
-       0x24, 0xF0, 0x90, 0x01, 0x9B, 0x74, 0x49, 0xF0,
-       0x90, 0x01, 0x9A, 0x74, 0xE0, 0xF0, 0x90, 0x01,
-       0x99, 0xE4, 0xF0, 0x90, 0x01, 0x98, 0x04, 0xF0,
-       0x22, 0xE4, 0x90, 0x81, 0x51, 0xF0, 0xA3, 0xF0,
-       0x90, 0x01, 0x98, 0xE0, 0x7F, 0x00, 0x30, 0xE4,
-       0x02, 0x7F, 0x01, 0xEF, 0x64, 0x01, 0x60, 0x3E,
-       0xC3, 0x90, 0x81, 0x52, 0xE0, 0x94, 0x88, 0x90,
-       0x81, 0x51, 0xE0, 0x94, 0x13, 0x40, 0x08, 0x90,
-       0x01, 0xC1, 0xE0, 0x44, 0x10, 0xF0, 0x22, 0x90,
-       0x81, 0x51, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x44,
-       0xA9, 0x7F, 0x14, 0x7E, 0x00, 0x12, 0x32, 0xAA,
-       0xD3, 0x90, 0x81, 0x52, 0xE0, 0x94, 0x32, 0x90,
-       0x81, 0x51, 0xE0, 0x94, 0x00, 0x40, 0xB9, 0x90,
-       0x01, 0xC6, 0xE0, 0x30, 0xE3, 0xB2, 0x22, 0xE4,
-       0x90, 0x81, 0x27, 0xF0, 0xA3, 0xF0, 0x90, 0x81,
-       0x26, 0xE0, 0x54, 0x0F, 0xF0, 0x54, 0xF0, 0xF0,
-       0x90, 0x81, 0x24, 0xE0, 0x54, 0xFD, 0xF0, 0x54,
-       0xF7, 0xF0, 0x54, 0xEF, 0xF0, 0x90, 0x81, 0x2D,
-       0x74, 0x01, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0x24,
-       0xE0, 0x54, 0xFB, 0xF0, 0xA3, 0xE0, 0x54, 0xFB,
-       0xF0, 0xE4, 0x90, 0x81, 0x30, 0xF0, 0x90, 0x81,
-       0x2F, 0x74, 0x07, 0xF0, 0x90, 0x81, 0x32, 0xE4,
-       0xF0, 0xA3, 0x74, 0x02, 0xF0, 0xE4, 0x90, 0x81,
-       0x2B, 0xF0, 0x90, 0x81, 0x24, 0xE0, 0x54, 0xFE,
-       0xF0, 0x90, 0x81, 0x29, 0x74, 0x0C, 0xF0, 0x90,
-       0x81, 0x24, 0xE0, 0x54, 0xDF, 0xF0, 0x90, 0x81,
-       0x2A, 0x74, 0x0C, 0xF0, 0x90, 0x81, 0x24, 0xE0,
-       0x54, 0xBF, 0xF0, 0x54, 0x7F, 0xF0, 0xA3, 0xE0,
-       0x54, 0xFE, 0xF0, 0x54, 0xFD, 0xF0, 0x54, 0xF7,
-       0xF0, 0x90, 0x81, 0x34, 0x12, 0x20, 0xDA, 0x00,
-       0x00, 0x00, 0x00, 0x90, 0x80, 0x3C, 0xE0, 0xB4,
-       0x01, 0x08, 0x90, 0x81, 0x31, 0x74, 0x99, 0xF0,
-       0x80, 0x12, 0x90, 0x80, 0x3C, 0xE0, 0x90, 0x81,
-       0x31, 0xB4, 0x03, 0x05, 0x74, 0x90, 0xF0, 0x80,
-       0x03, 0x74, 0x40, 0xF0, 0x90, 0x81, 0x38, 0x74,
-       0x01, 0xF0, 0xA3, 0x74, 0x05, 0xF0, 0xA3, 0xE0,
-       0x54, 0x01, 0x44, 0x28, 0xF0, 0xA3, 0x74, 0x05,
-       0xF0, 0xE4, 0xA3, 0xF0, 0xA3, 0xE0, 0x54, 0xFD,
-       0xF0, 0x54, 0xFB, 0xF0, 0x54, 0xF7, 0xF0, 0x54,
-       0xEF, 0xF0, 0x54, 0xDF, 0xF0, 0x54, 0xBF, 0xF0,
-       0xE4, 0xA3, 0xF0, 0x22, 0xE4, 0x90, 0x81, 0x59,
-       0xF0, 0x90, 0x81, 0x59, 0xE0, 0x64, 0x01, 0xF0,
-       0x24, 0x24, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x5C,
-       0xA3, 0xF0, 0x90, 0x81, 0x2A, 0xE0, 0xFF, 0x90,
-       0x81, 0x29, 0xE0, 0x6F, 0x60, 0x03, 0x12, 0x47,
-       0x2A, 0xD1, 0x08, 0xBF, 0x01, 0x02, 0x91, 0x5F,
-       0xB1, 0xF2, 0x12, 0x32, 0x9E, 0xBF, 0x01, 0x02,
-       0xB1, 0x67, 0x12, 0x42, 0x4D, 0x80, 0xCA, 0xD3,
-       0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81,
-       0x24, 0xE0, 0x30, 0xE0, 0x24, 0x90, 0x81, 0x1F,
-       0xE0, 0xFF, 0x30, 0xE0, 0x1A, 0xC3, 0x13, 0x30,
-       0xE0, 0x07, 0xB1, 0xFB, 0xBF, 0x01, 0x12, 0x80,
-       0x0A, 0x90, 0x81, 0x23, 0xE0, 0xFF, 0x60, 0x03,
-       0xB4, 0x08, 0x06, 0x91, 0x96, 0x80, 0x02, 0x91,
-       0xA6, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
-       0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0xB1, 0x22, 0x91,
-       0xBA, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x90, 0x81,
-       0x2A, 0xE0, 0x70, 0x0D, 0xD1, 0x2F, 0xBF, 0x01,
-       0x08, 0x91, 0x96, 0x90, 0x01, 0xE5, 0xE0, 0x04,
-       0xF0, 0x22, 0xB1, 0xF3, 0x90, 0x00, 0x08, 0xE0,
-       0x54, 0xEF, 0xFD, 0x7F, 0x08, 0x12, 0x32, 0x1E,
-       0xE4, 0xFF, 0x8F, 0x50, 0xE4, 0x90, 0x81, 0x5A,
-       0xF0, 0xA3, 0xF0, 0x90, 0x01, 0x09, 0xE0, 0x7F,
-       0x00, 0x30, 0xE7, 0x02, 0x7F, 0x01, 0xEF, 0x65,
-       0x50, 0x60, 0x3E, 0xC3, 0x90, 0x81, 0x5B, 0xE0,
-       0x94, 0x88, 0x90, 0x81, 0x5A, 0xE0, 0x94, 0x13,
-       0x40, 0x08, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x10,
-       0xF0, 0x22, 0x90, 0x81, 0x5A, 0xE4, 0x75, 0xF0,
-       0x01, 0x12, 0x44, 0xA9, 0x7F, 0x14, 0x7E, 0x00,
-       0x12, 0x32, 0xAA, 0xD3, 0x90, 0x81, 0x5B, 0xE0,
-       0x94, 0x32, 0x90, 0x81, 0x5A, 0xE0, 0x94, 0x00,
-       0x40, 0xB9, 0x90, 0x01, 0xC6, 0xE0, 0x30, 0xE0,
-       0xB2, 0x22, 0x90, 0x81, 0x31, 0xE0, 0xFD, 0x7F,
-       0x93, 0x12, 0x32, 0x1E, 0x90, 0x81, 0x28, 0xE0,
-       0x60, 0x12, 0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7,
-       0x05, 0x74, 0x10, 0xF0, 0x80, 0x06, 0x90, 0x01,
-       0x2F, 0x74, 0x90, 0xF0, 0x90, 0x00, 0x08, 0xE0,
-       0x44, 0x10, 0xFD, 0x7F, 0x08, 0x12, 0x32, 0x1E,
-       0x7F, 0x01, 0x91, 0xCA, 0x90, 0x00, 0x90, 0xE0,
-       0x44, 0x01, 0xFD, 0x7F, 0x90, 0x12, 0x32, 0x1E,
-       0x7F, 0x14, 0x7E, 0x00, 0x02, 0x32, 0xAA, 0xD3,
-       0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x2D,
-       0xA7, 0xE4, 0xF5, 0x52, 0x12, 0x32, 0x9E, 0xEF,
-       0x60, 0x73, 0x63, 0x52, 0x01, 0xE5, 0x52, 0x24,
-       0x67, 0x90, 0x01, 0xC4, 0xF0, 0x74, 0x5D, 0xA3,
-       0xF0, 0x90, 0x00, 0x88, 0xE0, 0xF5, 0x50, 0xF5,
-       0x51, 0x54, 0x0F, 0x60, 0xDF, 0xE5, 0x50, 0x30,
-       0xE0, 0x0B, 0x20, 0xE4, 0x03, 0x12, 0x29, 0xC5,
-       0x53, 0x51, 0xEE, 0x80, 0x3F, 0xE5, 0x50, 0x30,
-       0xE1, 0x16, 0x20, 0xE5, 0x0E, 0x12, 0x11, 0xBD,
-       0xEF, 0x70, 0x03, 0x43, 0x51, 0x20, 0x90, 0x01,
-       0x06, 0xE4, 0xF0, 0x53, 0x51, 0xFD, 0x80, 0x24,
-       0xE5, 0x50, 0x30, 0xE2, 0x0B, 0x20, 0xE6, 0x03,
-       0x12, 0x67, 0x06, 0x53, 0x51, 0xFB, 0x80, 0x14,
-       0xE5, 0x50, 0x30, 0xE3, 0x0F, 0x20, 0xE7, 0x09,
-       0x12, 0x61, 0x6E, 0xEF, 0x70, 0x03, 0x43, 0x51,
-       0x80, 0x53, 0x51, 0xF7, 0xAD, 0x51, 0x7F, 0x88,
-       0x12, 0x32, 0x1E, 0x80, 0x87, 0xD0, 0xD0, 0x92,
-       0xAF, 0x22, 0x22, 0x90, 0x00, 0x90, 0xE0, 0x20,
-       0xE0, 0xF9, 0x22, 0x90, 0x81, 0x22, 0xE0, 0x64,
-       0x02, 0x7F, 0x01, 0x60, 0x02, 0x7F, 0x00, 0x22,
-       0x7F, 0x02, 0x90, 0x81, 0x41, 0xE0, 0xFE, 0xEF,
-       0xC3, 0x9E, 0x50, 0x18, 0xEF, 0x25, 0xE0, 0x24,
-       0x81, 0xF8, 0xE6, 0x30, 0xE4, 0x0B, 0x90, 0x01,
-       0xB8, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x7F, 0x00,
-       0x22, 0x0F, 0x80, 0xDE, 0x7F, 0x01, 0x22, 0x90,
-       0x02, 0x87, 0xE0, 0x60, 0x08, 0x90, 0x01, 0xB8,
-       0x74, 0x01, 0xF0, 0x80, 0x17, 0x90, 0x02, 0x86,
-       0xE0, 0x20, 0xE1, 0x08, 0x90, 0x01, 0xB8, 0x74,
-       0x04, 0xF0, 0x80, 0x08, 0x90, 0x01, 0xB8, 0xE4,
-       0xF0, 0x7F, 0x01, 0x22, 0x90, 0x01, 0xB9, 0x74,
-       0x08, 0xF0, 0x7F, 0x00, 0x22, 0xE4, 0xFB, 0xFA,
-       0xFD, 0x7F, 0x01, 0x12, 0x44, 0x4E, 0x90, 0x81,
-       0xBD, 0xEF, 0xF0, 0x60, 0xF0, 0xD1, 0x71, 0x80,
-       0xEC, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
-       0x90, 0x01, 0xCC, 0xE0, 0x54, 0x0F, 0x90, 0x81,
-       0xBE, 0xF0, 0x90, 0x81, 0xBE, 0xE0, 0xFD, 0x70,
-       0x02, 0xE1, 0x9C, 0x90, 0x82, 0x09, 0xE0, 0xFF,
-       0x74, 0x01, 0x7E, 0x00, 0xA8, 0x07, 0x08, 0x80,
-       0x05, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9,
-       0xFF, 0xEF, 0x5D, 0x70, 0x02, 0xE1, 0x95, 0x90,
-       0x82, 0x09, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01,
-       0xD0, 0x12, 0x45, 0x0A, 0xE0, 0x90, 0x81, 0xBF,
-       0xF0, 0x75, 0x13, 0x01, 0x75, 0x14, 0x81, 0x75,
-       0x15, 0xBF, 0x75, 0x16, 0x01, 0x7B, 0x01, 0x7A,
-       0x81, 0x79, 0xC0, 0x12, 0x2B, 0xED, 0x90, 0x82,
-       0x09, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xD1,
-       0x12, 0x45, 0x0A, 0xE0, 0x90, 0x81, 0xC1, 0xF0,
-       0x90, 0x82, 0x09, 0xE0, 0x75, 0xF0, 0x04, 0x90,
-       0x01, 0xD2, 0x12, 0x45, 0x0A, 0xE0, 0x90, 0x81,
-       0xC2, 0xF0, 0x90, 0x82, 0x09, 0xE0, 0x75, 0xF0,
-       0x04, 0x90, 0x01, 0xD3, 0x12, 0x45, 0x0A, 0xE0,
-       0x90, 0x81, 0xC3, 0xF0, 0x90, 0x82, 0x09, 0xE0,
-       0x75, 0xF0, 0x04, 0x90, 0x01, 0xF0, 0x12, 0x45,
-       0x0A, 0xE0, 0x90, 0x81, 0xC4, 0xF0, 0x90, 0x82,
-       0x09, 0xE0, 0x75, 0xF0, 0x04, 0x90, 0x01, 0xF1,
-       0x12, 0x45, 0x0A, 0xE0, 0x90, 0x81, 0xC5, 0xF0,
-       0x90, 0x82, 0x09, 0xE0, 0x75, 0xF0, 0x04, 0x90,
-       0x01, 0xF2, 0x12, 0x45, 0x0A, 0xE0, 0x90, 0x81,
-       0xC6, 0xF0, 0x90, 0x82, 0x09, 0xE0, 0x75, 0xF0,
-       0x04, 0x90, 0x01, 0xF3, 0x12, 0x45, 0x0A, 0xE0,
-       0x90, 0x81, 0xC7, 0xF0, 0x90, 0x81, 0xBE, 0xE0,
-       0xFF, 0x90, 0x82, 0x09, 0xE0, 0xFE, 0x74, 0x01,
-       0xA8, 0x06, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
-       0xFC, 0xF4, 0x5F, 0x90, 0x81, 0xBE, 0xF0, 0x90,
-       0x82, 0x09, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07,
-       0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0x90,
-       0x01, 0xCC, 0xF0, 0x90, 0x81, 0xC0, 0xE0, 0xFF,
-       0x7B, 0x01, 0x7A, 0x81, 0x79, 0xC1, 0x12, 0x55,
-       0x3F, 0x90, 0x82, 0x09, 0xE0, 0x04, 0xF0, 0xE0,
-       0x54, 0x03, 0xF0, 0xC1, 0x82, 0x90, 0x01, 0xC0,
-       0xE0, 0x44, 0x02, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
-       0x22, 0xE4, 0xFB, 0xFA, 0xFD, 0x7F, 0x01, 0x12,
-       0x44, 0x4E, 0x90, 0x81, 0xD0, 0xEF, 0xF0, 0x60,
-       0xF0, 0x12, 0x6C, 0x19, 0x80, 0xEB, 0x90, 0x81,
-       0xD4, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0x12,
-       0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x90,
-       0x81, 0xE2, 0xF0, 0x7F, 0x24, 0x7E, 0x08, 0x12,
-       0x2D, 0x5C, 0x90, 0x81, 0xDA, 0x12, 0x20, 0xCE,
-       0x90, 0x81, 0xD4, 0xE0, 0xFB, 0x70, 0x08, 0x90,
-       0x81, 0xDA, 0x12, 0x44, 0xD9, 0x80, 0x16, 0xEB,
-       0x75, 0xF0, 0x08, 0xA4, 0x24, 0x62, 0xF5, 0x82,
-       0xE4, 0x34, 0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3,
-       0xE0, 0xFF, 0x12, 0x2D, 0x5C, 0x90, 0x81, 0xDE,
-       0x12, 0x20, 0xCE, 0x90, 0x81, 0xD5, 0xE0, 0xFF,
-       0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x17, 0x12, 0x20,
-       0xBB, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB,
-       0x07, 0x90, 0x81, 0xDE, 0x12, 0x44, 0xD9, 0xED,
-       0x54, 0x7F, 0xFD, 0xEC, 0x54, 0x80, 0xFC, 0x12,
-       0x44, 0xCC, 0xEC, 0x44, 0x80, 0xFC, 0x90, 0x81,
-       0xDE, 0x12, 0x20, 0xCE, 0x90, 0x81, 0xDA, 0x12,
-       0x44, 0xD9, 0xEC, 0x54, 0x7F, 0xFC, 0x90, 0x85,
-       0xBB, 0x12, 0x20, 0xCE, 0x7F, 0x24, 0x7E, 0x08,
-       0x12, 0x2E, 0xA2, 0x90, 0x81, 0xD4, 0xE0, 0x75,
-       0xF0, 0x08, 0xA4, 0x24, 0x62, 0xF5, 0x82, 0xE4,
-       0x34, 0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0,
-       0xFF, 0xC0, 0x06, 0xC0, 0x07, 0x90, 0x81, 0xDE,
-       0x12, 0x44, 0xD9, 0x90, 0x85, 0xBB, 0x12, 0x20,
-       0xCE, 0xD0, 0x07, 0xD0, 0x06, 0x12, 0x2E, 0xA2,
-       0x90, 0x81, 0xDA, 0x12, 0x44, 0xD9, 0xEC, 0x44,
-       0x80, 0xFC, 0x90, 0x85, 0xBB, 0x12, 0x20, 0xCE,
-       0x7F, 0x24, 0x7E, 0x08, 0x12, 0x2E, 0xA2, 0x90,
-       0x81, 0xD4, 0xE0, 0x70, 0x04, 0x7F, 0x20, 0x80,
-       0x09, 0x90, 0x81, 0xD4, 0xE0, 0xB4, 0x01, 0x16,
-       0x7F, 0x28, 0x7E, 0x08, 0x12, 0x2D, 0x5C, 0x78,
-       0x08, 0x12, 0x20, 0xA8, 0xEF, 0x54, 0x01, 0xFF,
-       0xE4, 0x90, 0x81, 0xE2, 0xEF, 0xF0, 0x90, 0x81,
-       0xE2, 0xE0, 0x90, 0x81, 0xD4, 0x60, 0x0E, 0xE0,
-       0x75, 0xF0, 0x08, 0xA4, 0x24, 0x66, 0xF5, 0x82,
-       0xE4, 0x34, 0x87, 0x80, 0x0C, 0xE0, 0x75, 0xF0,
-       0x08, 0xA4, 0x24, 0x64, 0xF5, 0x82, 0xE4, 0x34,
-       0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
-       0x12, 0x2D, 0x5C, 0xED, 0x54, 0x0F, 0xFD, 0xE4,
-       0xFC, 0x90, 0x81, 0xD6, 0x12, 0x20, 0xCE, 0x90,
-       0x81, 0xD6, 0x02, 0x44, 0xD9, 0x90, 0x81, 0xE3,
-       0xEF, 0xF0, 0xAB, 0x05, 0x90, 0x81, 0xE9, 0x12,
-       0x20, 0xDA, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x03,
-       0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x14, 0x12, 0x20,
-       0xBB, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB,
-       0x07, 0x90, 0x81, 0xE5, 0x12, 0x44, 0xD9, 0xED,
-       0x54, 0x0F, 0xFD, 0xE4, 0xFC, 0x12, 0x44, 0xCC,
-       0xEC, 0x54, 0x0F, 0xFC, 0x90, 0x81, 0xE9, 0x12,
-       0x20, 0xCE, 0x90, 0x81, 0xE3, 0xE0, 0x75, 0xF0,
-       0x08, 0xA4, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34,
-       0x87, 0xF5, 0x83, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
-       0xC0, 0x06, 0xC0, 0x07, 0x90, 0x81, 0xE9, 0x12,
-       0x44, 0xD9, 0x90, 0x85, 0xBB, 0x12, 0x20, 0xCE,
-       0xD0, 0x07, 0xD0, 0x06, 0x02, 0x2E, 0xA2, 0xD3,
-       0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x12, 0x5F,
-       0xB6, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0x78, 0x10,
-       0x74, 0x01, 0xF2, 0x90, 0x02, 0x09, 0xE0, 0x78,
-       0x00, 0xF2, 0x08, 0x74, 0x20, 0xF2, 0x18, 0xE2,
-       0xFF, 0x30, 0xE0, 0x05, 0x08, 0xE2, 0x24, 0x80,
-       0xF2, 0xEF, 0xC3, 0x13, 0x90, 0xFD, 0x10, 0xF0,
-       0x78, 0x01, 0xE2, 0x24, 0x00, 0xF5, 0x82, 0xE4,
-       0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x78, 0x03, 0xF2,
-       0x64, 0x04, 0x60, 0x0D, 0xE2, 0xFF, 0x64, 0x08,
-       0x60, 0x07, 0xEF, 0x64, 0x0C, 0x60, 0x02, 0x61,
-       0xDE, 0xE4, 0x78, 0x02, 0xF2, 0x78, 0x03, 0xE2,
-       0xFF, 0x18, 0xE2, 0xC3, 0x9F, 0x50, 0x2D, 0xE2,
-       0xFD, 0x18, 0xE2, 0x2D, 0x90, 0x81, 0x5A, 0xF0,
-       0xE0, 0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34,
-       0xFC, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x04, 0x2D,
-       0xF8, 0xEE, 0xF2, 0xEF, 0xB4, 0xFF, 0x06, 0x90,
-       0xFD, 0x10, 0xE0, 0x04, 0xF0, 0x78, 0x02, 0xE2,
-       0x04, 0xF2, 0x80, 0xC9, 0x78, 0x04, 0xE2, 0x78,
-       0x12, 0xF2, 0xFF, 0x78, 0x05, 0xE2, 0x78, 0x11,
-       0xF2, 0x78, 0x06, 0xE2, 0x78, 0x13, 0xF2, 0x78,
-       0x07, 0xE2, 0x78, 0x14, 0xF2, 0x78, 0x08, 0xE2,
-       0x78, 0x33, 0xF2, 0x78, 0x09, 0xE2, 0x78, 0x34,
-       0xF2, 0x78, 0x0A, 0xE2, 0x78, 0x35, 0xF2, 0x78,
-       0x0B, 0xE2, 0x78, 0x36, 0xF2, 0x78, 0x0C, 0xE2,
-       0x78, 0x37, 0xF2, 0x78, 0x0D, 0xE2, 0x78, 0x38,
-       0xF2, 0x78, 0x0E, 0xE2, 0x78, 0x39, 0xF2, 0x78,
-       0x0F, 0xE2, 0x78, 0x3A, 0xF2, 0xE4, 0x78, 0x15,
-       0xF2, 0xEF, 0x24, 0xF8, 0x60, 0x75, 0x24, 0xFC,
-       0x60, 0x6C, 0x24, 0x08, 0x60, 0x02, 0x61, 0xC0,
-       0x78, 0x11, 0xE2, 0xB4, 0x01, 0x05, 0x12, 0x29,
-       0xC5, 0x61, 0xC5, 0x78, 0x11, 0xE2, 0xB4, 0x02,
-       0x05, 0x12, 0x11, 0xBD, 0x61, 0xC5, 0x78, 0x11,
-       0xE2, 0xB4, 0x03, 0x04, 0xF1, 0x06, 0x61, 0xC5,
-       0x78, 0x11, 0xE2, 0xB4, 0x10, 0x17, 0x78, 0x14,
-       0xE2, 0xFE, 0x18, 0xE2, 0xFD, 0xED, 0xFF, 0x78,
-       0x16, 0xEE, 0xF2, 0xFE, 0x08, 0xEF, 0xF2, 0xFF,
-       0x12, 0x32, 0xAA, 0x61, 0xC5, 0x78, 0x11, 0xE2,
-       0xB4, 0x11, 0x17, 0x78, 0x14, 0xE2, 0xFE, 0x18,
-       0xE2, 0xFD, 0xED, 0xFF, 0x78, 0x16, 0xEE, 0xF2,
-       0xFE, 0x08, 0xEF, 0xF2, 0xFF, 0x12, 0x32, 0x06,
-       0x61, 0xC5, 0x78, 0x11, 0xE2, 0xF4, 0x60, 0x02,
-       0x61, 0xC5, 0x18, 0xF2, 0x61, 0xC5, 0x78, 0x15,
-       0x74, 0x01, 0xF2, 0x78, 0x11, 0xE2, 0x64, 0x07,
-       0x60, 0x02, 0x61, 0xAA, 0x78, 0x34, 0xE2, 0xFF,
-       0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x08, 0x12, 0x20,
-       0xBB, 0xC0, 0x04, 0xA9, 0x05, 0xAA, 0x06, 0xAB,
-       0x07, 0x78, 0x33, 0xE2, 0xFF, 0xE4, 0xFC, 0xFD,
-       0xFE, 0xD0, 0x00, 0x12, 0x44, 0xCC, 0xC0, 0x04,
-       0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x78, 0x35,
-       0xE2, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x10,
-       0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
-       0x01, 0xD0, 0x00, 0x12, 0x44, 0xCC, 0x78, 0x18,
-       0x12, 0x44, 0xFE, 0x78, 0x15, 0xE2, 0x70, 0x02,
-       0x61, 0x93, 0x18, 0xE2, 0xFF, 0x18, 0xE2, 0xFD,
-       0x31, 0x5F, 0x78, 0x1C, 0x12, 0x44, 0xFE, 0x78,
-       0x38, 0xE2, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78,
-       0x08, 0x12, 0x20, 0xBB, 0xC0, 0x04, 0xA9, 0x05,
-       0xAA, 0x06, 0xAB, 0x07, 0x78, 0x37, 0xE2, 0xFF,
-       0xE4, 0xFC, 0xFD, 0xFE, 0xD0, 0x00, 0x12, 0x44,
-       0xCC, 0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0,
-       0x07, 0x78, 0x39, 0xE2, 0xFF, 0xE4, 0xFC, 0xFD,
-       0xFE, 0x78, 0x10, 0x12, 0x20, 0xBB, 0xD0, 0x03,
-       0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00, 0x12, 0x44,
-       0xCC, 0x78, 0x20, 0x12, 0x44, 0xFE, 0x78, 0x20,
-       0x12, 0x44, 0xE5, 0x12, 0x20, 0x9B, 0x78, 0x1C,
-       0x12, 0x44, 0xF1, 0x12, 0x44, 0xBF, 0xC0, 0x04,
-       0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07, 0x78, 0x18,
-       0x12, 0x44, 0xE5, 0x78, 0x20, 0x12, 0x44, 0xF1,
-       0x12, 0x44, 0xBF, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
-       0x01, 0xD0, 0x00, 0x12, 0x44, 0xCC, 0x78, 0x18,
-       0x12, 0x44, 0xFE, 0x78, 0x18, 0x12, 0x44, 0xE5,
-       0x90, 0x81, 0xF9, 0x12, 0x20, 0xCE, 0x78, 0x13,
-       0xE2, 0xFD, 0x08, 0xE2, 0xFF, 0x12, 0x55, 0x1C,
-       0x80, 0x1B, 0x78, 0x13, 0xE2, 0xFF, 0x08, 0xE2,
-       0xFD, 0x78, 0x11, 0xE2, 0xFB, 0x78, 0x15, 0xE2,
-       0x90, 0x81, 0xBC, 0xF0, 0x71, 0xE1, 0x80, 0x05,
-       0x78, 0x10, 0x74, 0x02, 0xF2, 0x78, 0x10, 0xE2,
-       0xFF, 0xC3, 0x94, 0x02, 0x50, 0x10, 0xEF, 0x60,
-       0x0A, 0x78, 0x02, 0xE2, 0xFF, 0x18, 0xE2, 0x2F,
-       0xF2, 0x21, 0x90, 0x7F, 0x01, 0x22, 0x7F, 0x00,
-       0x22, 0xAC, 0x07, 0xED, 0xAD, 0x04, 0x78, 0x24,
-       0xF2, 0xED, 0x08, 0xF2, 0xEB, 0xB4, 0x04, 0x07,
-       0x78, 0x27, 0x74, 0x01, 0xF2, 0x80, 0x0E, 0xEB,
-       0x78, 0x27, 0xB4, 0x05, 0x05, 0x74, 0x02, 0xF2,
-       0x80, 0x03, 0x74, 0x04, 0xF2, 0xD3, 0x78, 0x25,
-       0xE2, 0x94, 0xFF, 0x18, 0xE2, 0x94, 0x00, 0x50,
-       0x63, 0xE4, 0x78, 0x26, 0xF2, 0x78, 0x27, 0xE2,
-       0xFF, 0x18, 0xE2, 0xFE, 0xC3, 0x9F, 0x40, 0x02,
-       0xA1, 0x7F, 0x74, 0x33, 0x2E, 0xF8, 0xE2, 0x78,
-       0x28, 0xF2, 0x90, 0x81, 0xBC, 0xE0, 0x60, 0x2D,
-       0x74, 0x37, 0x2E, 0xF8, 0xE2, 0x78, 0x32, 0xF2,
-       0xEE, 0xFF, 0x78, 0x25, 0xE2, 0x2F, 0xFF, 0x18,
-       0xE2, 0x34, 0x00, 0x8F, 0x82, 0xF5, 0x83, 0xE0,
-       0x78, 0x29, 0xF2, 0x78, 0x32, 0xE2, 0xFF, 0xF4,
-       0xFE, 0x78, 0x29, 0xE2, 0x5E, 0xFE, 0x18, 0xE2,
-       0xFD, 0xEF, 0x5D, 0x4E, 0xF2, 0x78, 0x24, 0x08,
-       0xE2, 0xFF, 0x08, 0xE2, 0x2F, 0xFF, 0x78, 0x28,
-       0xE2, 0xFD, 0x12, 0x32, 0x1E, 0x78, 0x26, 0xE2,
-       0x04, 0xF2, 0x80, 0xA1, 0xD3, 0x78, 0x25, 0xE2,
-       0x94, 0xFF, 0x18, 0xE2, 0x94, 0x07, 0x50, 0x69,
-       0xE4, 0x78, 0x26, 0xF2, 0x78, 0x27, 0xE2, 0xFF,
-       0x18, 0xE2, 0xFE, 0xC3, 0x9F, 0x40, 0x02, 0xA1,
-       0x7F, 0x74, 0x33, 0x2E, 0xF8, 0xE2, 0x78, 0x28,
-       0xF2, 0x90, 0x81, 0xBC, 0xE0, 0x60, 0x2D, 0x78,
-       0x26, 0xE2, 0xFF, 0xFD, 0x18, 0xE2, 0x2D, 0xFD,
-       0x18, 0xE2, 0x34, 0x00, 0x8D, 0x82, 0xF5, 0x83,
-       0xE0, 0x78, 0x29, 0xF2, 0x74, 0x37, 0x2F, 0xF8,
-       0xE2, 0x78, 0x32, 0xF2, 0xE2, 0xFF, 0xF4, 0xFE,
-       0x78, 0x29, 0xE2, 0x5E, 0xFE, 0x18, 0xE2, 0xFD,
-       0xEF, 0x5D, 0x4E, 0xF2, 0x78, 0x28, 0xE2, 0xFF,
-       0x78, 0x26, 0xE2, 0xFD, 0x18, 0xE2, 0x2D, 0xFD,
-       0x18, 0xE2, 0x34, 0x00, 0x8D, 0x82, 0xF5, 0x83,
-       0xEF, 0xF0, 0x78, 0x26, 0xE2, 0x04, 0xF2, 0x80,
-       0x9B, 0x90, 0x81, 0xBC, 0xE0, 0x60, 0x0F, 0x78,
-       0x24, 0xE2, 0xFE, 0x08, 0xE2, 0xFF, 0x12, 0x2D,
-       0x5C, 0x78, 0x2E, 0x12, 0x44, 0xFE, 0xE4, 0x78,
-       0x26, 0xF2, 0x78, 0x27, 0xE2, 0xFF, 0x18, 0xE2,
-       0xFE, 0xC3, 0x9F, 0x50, 0x5D, 0x74, 0x33, 0x2E,
-       0xF8, 0xE2, 0x78, 0x28, 0xF2, 0x90, 0x81, 0xBC,
-       0xE0, 0x60, 0x2B, 0x78, 0x2E, 0x12, 0x44, 0xE5,
-       0x78, 0x26, 0xE2, 0xFB, 0x75, 0xF0, 0x08, 0xA4,
-       0xF9, 0xF8, 0x12, 0x20, 0xA8, 0x78, 0x29, 0xEF,
-       0xF2, 0x74, 0x37, 0x2B, 0xF8, 0xE2, 0x78, 0x32,
-       0xF2, 0xE2, 0xFE, 0xF4, 0x5F, 0xFF, 0x78, 0x28,
-       0xE2, 0xFD, 0xEE, 0x5D, 0x4F, 0xF2, 0x78, 0x28,
-       0xE2, 0xFF, 0x78, 0x26, 0xE2, 0xFD, 0xC3, 0x74,
-       0x03, 0x9D, 0xFD, 0xE4, 0x94, 0x00, 0xFC, 0x7B,
-       0xFE, 0x74, 0x2A, 0x2D, 0xF9, 0x74, 0x80, 0x3C,
-       0xFA, 0xEF, 0x12, 0x1F, 0xEA, 0xE2, 0x04, 0xF2,
-       0x80, 0x98, 0x78, 0x2A, 0x12, 0x44, 0xE5, 0x90,
-       0x85, 0xBB, 0x12, 0x20, 0xCE, 0x78, 0x24, 0xE2,
-       0xFE, 0x08, 0xE2, 0xFF, 0x12, 0x2E, 0xA2, 0x22,
-       0x22, 0x90, 0x81, 0xCB, 0x12, 0x45, 0x1F, 0x90,
-       0x00, 0x01, 0x12, 0x1F, 0xBD, 0xFF, 0xFE, 0x12,
-       0x1F, 0xA4, 0xFD, 0xC3, 0x13, 0x30, 0xE0, 0x12,
-       0x90, 0x81, 0xCB, 0x12, 0x45, 0x16, 0x90, 0x00,
-       0x02, 0x12, 0x1F, 0xBD, 0x90, 0x81, 0xCF, 0xF0,
-       0x80, 0x05, 0x90, 0x81, 0xCF, 0xEF, 0xF0, 0x90,
-       0x81, 0xCE, 0xEE, 0xF0, 0x90, 0x81, 0xCF, 0xE0,
-       0xFE, 0x90, 0x81, 0xCE, 0xE0, 0xFF, 0xD3, 0x9E,
-       0x50, 0x38, 0x90, 0x81, 0xCB, 0x12, 0x45, 0x16,
-       0x12, 0x1F, 0xA4, 0x54, 0x01, 0xFE, 0x74, 0xDE,
-       0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x80, 0xF5, 0x83,
-       0xEE, 0xF0, 0x74, 0xDE, 0x2F, 0xF5, 0x82, 0xE4,
-       0x34, 0x80, 0xF5, 0x83, 0xE0, 0x70, 0x04, 0xD1,
-       0x25, 0x80, 0x07, 0x90, 0x81, 0xCE, 0xE0, 0xFF,
-       0xB1, 0x80, 0x90, 0x81, 0xCE, 0xE0, 0x04, 0xF0,
-       0x80, 0xBA, 0x90, 0x80, 0xDE, 0xE0, 0x70, 0x24,
-       0x90, 0x81, 0x2A, 0xE0, 0x70, 0x04, 0xFF, 0x12,
-       0x49, 0x93, 0x90, 0x81, 0x2A, 0xE0, 0x64, 0x0C,
-       0x60, 0x02, 0xD1, 0x26, 0x90, 0x81, 0x24, 0xE0,
-       0x54, 0xF7, 0xF0, 0x54, 0xEF, 0xF0, 0x54, 0xBF,
-       0xF0, 0x54, 0x7F, 0xF0, 0x22, 0x22, 0x90, 0x06,
-       0x04, 0xE0, 0x54, 0x7F, 0xF0, 0x90, 0x05, 0x22,
-       0xE4, 0xF0, 0x90, 0x81, 0x2A, 0x74, 0x0C, 0xF0,
-       0x22, 0x90, 0x81, 0xED, 0xEF, 0xF0, 0xA3, 0xED,
-       0xF0, 0xAD, 0x03, 0xAC, 0x02, 0xE4, 0x90, 0x81,
-       0xF5, 0xF0, 0xA3, 0xF0, 0x90, 0x01, 0xC4, 0x74,
-       0x39, 0xF0, 0x74, 0x66, 0xA3, 0xF0, 0xEC, 0x54,
-       0x3F, 0xFC, 0x90, 0x01, 0x40, 0xED, 0xF0, 0xAE,
-       0x04, 0xEE, 0xA3, 0xF0, 0x90, 0x81, 0xED, 0xE0,
-       0x24, 0x81, 0x60, 0x34, 0x24, 0xDA, 0x60, 0x1C,
-       0x24, 0x3C, 0x70, 0x41, 0x90, 0x81, 0xEE, 0xE0,
-       0xC4, 0x33, 0x33, 0x33, 0x54, 0x80, 0x90, 0x81,
-       0xF2, 0xF0, 0xA3, 0x74, 0x69, 0xF0, 0xA3, 0x74,
-       0x80, 0xF0, 0x80, 0x2C, 0x90, 0x81, 0xEE, 0xE0,
-       0x54, 0x01, 0x90, 0x81, 0xF2, 0xF0, 0xA3, 0x74,
-       0xA5, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0x80, 0x18,
-       0x90, 0x81, 0xEE, 0xE0, 0xC4, 0x54, 0x10, 0x90,
-       0x81, 0xF2, 0xF0, 0xA3, 0x74, 0x7F, 0xF0, 0xA3,
-       0x74, 0x10, 0xF0, 0x80, 0x03, 0x7F, 0x00, 0x22,
-       0x90, 0x81, 0xF3, 0xE0, 0x90, 0x01, 0x06, 0xF0,
-       0x90, 0x81, 0xF2, 0xE0, 0x60, 0x0E, 0x90, 0x01,
-       0x42, 0xF0, 0x90, 0x81, 0xF1, 0xE0, 0x90, 0x01,
-       0x43, 0xF0, 0x80, 0x0D, 0x90, 0x01, 0x43, 0xE4,
-       0xF0, 0x90, 0x81, 0xF2, 0xE0, 0x90, 0x01, 0x42,
-       0xF0, 0x90, 0x81, 0xF4, 0xE0, 0xFF, 0x90, 0x01,
-       0x42, 0xE0, 0x5F, 0xFF, 0x90, 0x81, 0xF2, 0xE0,
-       0x6F, 0x60, 0xEE, 0x74, 0x39, 0x04, 0x90, 0x01,
-       0xC4, 0xF0, 0x74, 0x66, 0xA3, 0xF0, 0x90, 0x01,
-       0x43, 0xE4, 0xF0, 0x7F, 0x01, 0x22, 0xE4, 0x90,
-       0x81, 0x6A, 0xF0, 0x90, 0x87, 0x5F, 0xE0, 0x90,
-       0x81, 0x69, 0xF0, 0xE4, 0x90, 0x81, 0x76, 0xF0,
-       0x90, 0x81, 0x66, 0xF0, 0x90, 0x81, 0x66, 0xE0,
-       0xFF, 0xC3, 0x94, 0x40, 0x50, 0x15, 0x74, 0x79,
-       0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83,
-       0x74, 0xFF, 0xF0, 0x90, 0x81, 0x66, 0xE0, 0x04,
-       0xF0, 0x80, 0xE1, 0xE4, 0x90, 0x81, 0x66, 0xF0,
-       0x90, 0x81, 0x69, 0xE0, 0xFF, 0x90, 0x81, 0x66,
-       0xE0, 0xFE, 0xC3, 0x9F, 0x40, 0x03, 0x02, 0x68,
-       0x12, 0x74, 0xDF, 0x2E, 0xF9, 0xE4, 0x34, 0x86,
-       0x75, 0x13, 0x01, 0xF5, 0x14, 0x89, 0x15, 0x75,
-       0x16, 0x0A, 0x7B, 0x01, 0x7A, 0x81, 0x79, 0x5B,
-       0x12, 0x2B, 0xED, 0x90, 0x81, 0x5C, 0xE0, 0xFF,
-       0x12, 0x2F, 0x27, 0xEF, 0x04, 0x90, 0x81, 0x76,
-       0xF0, 0x90, 0x81, 0x5B, 0xE0, 0xFF, 0xA3, 0xE0,
-       0xFD, 0x12, 0x31, 0xEA, 0xEF, 0x24, 0xC8, 0x90,
-       0x81, 0x78, 0xF0, 0x75, 0xF0, 0x08, 0xA4, 0xF0,
-       0x90, 0x81, 0x5C, 0xE0, 0x54, 0x0F, 0x90, 0x81,
-       0x77, 0xF0, 0xE4, 0x90, 0x81, 0x65, 0xF0, 0x90,
-       0x81, 0x67, 0xF0, 0x90, 0x81, 0x67, 0xE0, 0xFF,
-       0xC3, 0x94, 0x04, 0x50, 0x57, 0x90, 0x81, 0x77,
-       0xE0, 0xFE, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3,
-       0x13, 0xD8, 0xFC, 0x20, 0xE0, 0x3E, 0x90, 0x81,
-       0x67, 0xE0, 0x25, 0xE0, 0xFF, 0x90, 0x81, 0x78,
-       0xE0, 0x2F, 0x24, 0x79, 0xF9, 0xE4, 0x34, 0x81,
-       0xFA, 0x7B, 0x01, 0xC0, 0x03, 0xC0, 0x01, 0x90,
-       0x81, 0x65, 0xE0, 0x75, 0xF0, 0x02, 0xA4, 0x24,
-       0x5D, 0xF9, 0x74, 0x81, 0x35, 0xF0, 0x8B, 0x13,
-       0xF5, 0x14, 0x89, 0x15, 0x75, 0x16, 0x02, 0xD0,
-       0x01, 0xD0, 0x03, 0x12, 0x2B, 0xED, 0x90, 0x81,
-       0x65, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x67, 0xE0,
-       0x04, 0xF0, 0x80, 0x9F, 0x90, 0x81, 0x76, 0xE0,
-       0xFF, 0x90, 0x81, 0x66, 0xE0, 0x2F, 0xF0, 0x02,
-       0x67, 0x40, 0xE4, 0x90, 0x81, 0x6A, 0xF0, 0x90,
-       0x81, 0x6A, 0xE0, 0xC3, 0x94, 0x40, 0x40, 0x02,
-       0x41, 0xAF, 0xE0, 0xFF, 0x24, 0x79, 0xF5, 0x82,
-       0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0x90, 0x81,
-       0x6C, 0xF0, 0xE0, 0xFE, 0x54, 0xF0, 0xC4, 0x54,
-       0x0F, 0xFD, 0x90, 0x81, 0x6B, 0xF0, 0xEE, 0x54,
-       0x0F, 0xFE, 0xA3, 0xF0, 0x74, 0x7A, 0x2F, 0xF5,
-       0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0x90,
-       0x81, 0x6D, 0xF0, 0xFC, 0xEE, 0xFE, 0xEC, 0xFB,
-       0xEB, 0xFF, 0x90, 0x81, 0x72, 0xEE, 0xF0, 0xA3,
-       0xEF, 0xF0, 0xED, 0x12, 0x45, 0x28, 0x68, 0x8B,
-       0x00, 0x68, 0xC2, 0x01, 0x69, 0x73, 0x02, 0x6A,
-       0xA0, 0x03, 0x69, 0x8E, 0x04, 0x69, 0xAF, 0x05,
-       0x69, 0xAF, 0x06, 0x69, 0xAF, 0x07, 0x69, 0xAF,
-       0x08, 0x6A, 0x33, 0x09, 0x6A, 0x69, 0x0A, 0x00,
-       0x00, 0x6A, 0xAF, 0x90, 0x81, 0x6A, 0xE0, 0xFD,
-       0x24, 0x7C, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5,
-       0x83, 0xE0, 0xFE, 0x74, 0x7B, 0x2D, 0xF5, 0x82,
-       0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0xFD, 0xED,
-       0xFF, 0x90, 0x81, 0x74, 0xEE, 0xF0, 0xFC, 0xA3,
-       0xEF, 0xF0, 0x90, 0x81, 0x6D, 0xE0, 0xFF, 0x12,
-       0x2F, 0x96, 0x90, 0x81, 0x68, 0x74, 0x02, 0xF0,
-       0x41, 0xA0, 0x90, 0x81, 0x6A, 0xE0, 0x24, 0x7C,
-       0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0,
-       0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x08, 0x12,
-       0x20, 0xBB, 0xA8, 0x04, 0xA9, 0x05, 0xAA, 0x06,
-       0xAB, 0x07, 0x90, 0x81, 0x6A, 0xE0, 0x24, 0x7B,
-       0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0,
-       0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x12, 0x44, 0xCC,
-       0xC0, 0x04, 0xC0, 0x05, 0xC0, 0x06, 0xC0, 0x07,
-       0x90, 0x81, 0x6A, 0xE0, 0x24, 0x7D, 0xF5, 0x82,
-       0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0xFF, 0xE4,
-       0xFC, 0xFD, 0xFE, 0x78, 0x10, 0x12, 0x20, 0xBB,
-       0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0, 0x00,
-       0x12, 0x44, 0xCC, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
-       0x06, 0xC0, 0x07, 0x90, 0x81, 0x6A, 0xE0, 0x24,
-       0x7E, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83,
-       0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x18,
-       0x12, 0x20, 0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0,
-       0x01, 0xD0, 0x00, 0x12, 0x44, 0xCC, 0x90, 0x81,
-       0x6E, 0x12, 0x20, 0xCE, 0x90, 0x81, 0x6E, 0x12,
-       0x44, 0xD9, 0x90, 0x85, 0x96, 0x12, 0x20, 0xCE,
-       0x90, 0x81, 0x72, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF,
-       0x12, 0x2E, 0xE4, 0x90, 0x81, 0x68, 0x74, 0x04,
-       0xF0, 0x41, 0xA0, 0x90, 0x81, 0x6D, 0xE0, 0xFD,
-       0x90, 0x81, 0x6A, 0xE0, 0x24, 0x7B, 0xF5, 0x82,
-       0xE4, 0x34, 0x81, 0xF5, 0x83, 0xE0, 0xFB, 0xE4,
-       0xFF, 0x12, 0x30, 0xC7, 0x80, 0x19, 0x90, 0x81,
-       0x6D, 0xE0, 0xFD, 0x90, 0x81, 0x6A, 0xE0, 0x24,
-       0x7B, 0xF5, 0x82, 0xE4, 0x34, 0x81, 0xF5, 0x83,
-       0xE0, 0xFB, 0xE4, 0xFF, 0x12, 0x30, 0x6A, 0x90,
-       0x81, 0x68, 0x74, 0x01, 0xF0, 0x41, 0xA0, 0x90,
-       0x81, 0x68, 0x74, 0x02, 0xF0, 0x90, 0x81, 0x6A,
-       0xE0, 0x24, 0x7C, 0xF5, 0x82, 0xE4, 0x34, 0x81,
-       0xF5, 0x83, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE,
-       0x78, 0x08, 0x12, 0x20, 0xBB, 0xA8, 0x04, 0xA9,
-       0x05, 0xAA, 0x06, 0xAB, 0x07, 0x90, 0x81, 0x6A,
-       0xE0, 0x24, 0x7B, 0xF5, 0x82, 0xE4, 0x34, 0x81,
-       0xF5, 0x83, 0xE0, 0xFF, 0xE4, 0xFC, 0xFD, 0xFE,
-       0x12, 0x44, 0xCC, 0xC0, 0x04, 0xC0, 0x05, 0xC0,
-       0x06, 0xC0, 0x07, 0x90, 0x81, 0x6C, 0xE0, 0xFF,
-       0xE4, 0xFC, 0xFD, 0xFE, 0x78, 0x10, 0x12, 0x20,
-       0xBB, 0xD0, 0x03, 0xD0, 0x02, 0xD0, 0x01, 0xD0,
-       0x00, 0x12, 0x44, 0xCC, 0x90, 0x81, 0x6E, 0x12,
-       0x20, 0xCE, 0x90, 0x81, 0x6B, 0xE0, 0x24, 0xFB,
-       0xFF, 0xC0, 0x07, 0x90, 0x81, 0x6E, 0x12, 0x44,
-       0xD9, 0x90, 0x81, 0xF9, 0x12, 0x20, 0xCE, 0x90,
-       0x81, 0x6D, 0xE0, 0xFD, 0xD0, 0x07, 0x12, 0x55,
-       0x1C, 0x80, 0x6D, 0x90, 0x81, 0x68, 0x74, 0x01,
-       0xF0, 0x90, 0x81, 0x6A, 0xE0, 0x24, 0x7B, 0xF9,
-       0xE4, 0x34, 0x81, 0x75, 0x13, 0x01, 0xF5, 0x14,
-       0x89, 0x15, 0x75, 0x16, 0x01, 0x7B, 0xFE, 0x7A,
-       0x80, 0x79, 0x33, 0x12, 0x2B, 0xED, 0x90, 0x81,
-       0x6D, 0xE0, 0xFF, 0x90, 0x81, 0x6C, 0xE0, 0xFD,
-       0xE4, 0x90, 0x81, 0xBC, 0xF0, 0x7B, 0x04, 0x80,
-       0x34, 0x90, 0x81, 0x68, 0x74, 0x04, 0xF0, 0x90,
-       0x81, 0x6A, 0xE0, 0x24, 0x7B, 0xF9, 0xE4, 0x34,
-       0x81, 0x75, 0x13, 0x01, 0xF5, 0x14, 0x89, 0x15,
-       0x75, 0x16, 0x04, 0x7B, 0xFE, 0x7A, 0x80, 0x79,
-       0x33, 0x12, 0x2B, 0xED, 0x90, 0x81, 0x6D, 0xE0,
-       0xFF, 0x90, 0x81, 0x6C, 0xE0, 0xFD, 0xE4, 0x90,
-       0x81, 0xBC, 0xF0, 0x7B, 0x06, 0x12, 0x63, 0xE1,
-       0x90, 0x81, 0x68, 0xE0, 0x24, 0x02, 0xFF, 0x90,
-       0x81, 0x6A, 0xE0, 0x2F, 0xF0, 0x01, 0x17, 0x22,
-       0x90, 0x02, 0x09, 0xE0, 0xFD, 0x12, 0x1F, 0xA4,
-       0xFE, 0xAF, 0x05, 0xED, 0x2E, 0x90, 0x80, 0x3D,
-       0xF0, 0x90, 0x00, 0x01, 0x12, 0x1F, 0xBD, 0xFF,
-       0xED, 0x2F, 0x90, 0x80, 0x3E, 0xF0, 0x90, 0x00,
-       0x02, 0x12, 0x1F, 0xBD, 0xFF, 0xED, 0x2F, 0x90,
-       0x80, 0x3F, 0xF0, 0x90, 0x00, 0x03, 0x12, 0x1F,
-       0xBD, 0xFF, 0xED, 0x2F, 0x90, 0x80, 0x40, 0xF0,
-       0x90, 0x00, 0x04, 0x12, 0x1F, 0xBD, 0xFF, 0xAE,
-       0x05, 0xED, 0x2F, 0x90, 0x80, 0x41, 0xF0, 0x22,
-       0x90, 0x00, 0x02, 0x12, 0x1F, 0xBD, 0xFF, 0x30,
-       0xE0, 0x26, 0x12, 0x1F, 0xA4, 0x90, 0x81, 0x38,
-       0xF0, 0x90, 0x00, 0x01, 0x12, 0x1F, 0xBD, 0x90,
-       0x81, 0x39, 0xF0, 0xEF, 0x54, 0xFE, 0xFF, 0xA3,
-       0xE0, 0x54, 0x01, 0x4F, 0xF0, 0x90, 0x00, 0x03,
-       0x12, 0x1F, 0xBD, 0x90, 0x81, 0x3B, 0xF0, 0x22,
-       0x90, 0x81, 0x38, 0x74, 0x01, 0xF0, 0xA3, 0x74,
-       0x05, 0xF0, 0xA3, 0xE0, 0x54, 0x01, 0x44, 0x28,
-       0xF0, 0xA3, 0x74, 0x05, 0xF0, 0x22, 0x12, 0x1F,
-       0xA4, 0x90, 0x81, 0x3E, 0xF0, 0x90, 0x81, 0x3E,
-       0xE0, 0x90, 0x01, 0xE7, 0xF0, 0x22, 0x12, 0x1F,
-       0xA4, 0x90, 0x81, 0x4A, 0xF0, 0x90, 0x00, 0x01,
-       0x12, 0x1F, 0xBD, 0x90, 0x81, 0x4B, 0xF0, 0x22,
-       0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90,
-       0x81, 0xFD, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0xE4,
-       0xA3, 0xF0, 0xA3, 0xF0, 0x90, 0x81, 0xFD, 0xE0,
-       0xFE, 0xA3, 0xE0, 0xF5, 0x82, 0x8E, 0x83, 0xE0,
-       0x60, 0x2D, 0xC3, 0x90, 0x82, 0x00, 0xE0, 0x94,
-       0xE8, 0x90, 0x81, 0xFF, 0xE0, 0x94, 0x03, 0x40,
-       0x0B, 0x90, 0x01, 0xC0, 0xE0, 0x44, 0x80, 0xF0,
-       0x7F, 0x00, 0x80, 0x15, 0x90, 0x81, 0xFF, 0xE4,
-       0x75, 0xF0, 0x01, 0x12, 0x44, 0xA9, 0x7F, 0x0A,
-       0x7E, 0x00, 0x12, 0x32, 0xAA, 0x80, 0xC5, 0x7F,
-       0x01, 0xD0, 0xD0, 0x92, 0xAF, 0x22, 0xD3, 0x10,
-       0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x81, 0xD1,
-       0x12, 0x45, 0x1F, 0x90, 0x82, 0x0A, 0xE0, 0xFF,
-       0x04, 0xF0, 0x90, 0x00, 0x01, 0xEF, 0x12, 0x1F,
-       0xFC, 0x7F, 0xAF, 0x7E, 0x01, 0x71, 0x60, 0xEF,
-       0x60, 0x3A, 0x90, 0x81, 0xD1, 0x12, 0x45, 0x16,
-       0x8B, 0x13, 0x8A, 0x14, 0x89, 0x15, 0x90, 0x00,
-       0x0E, 0x12, 0x1F, 0xBD, 0x24, 0x02, 0xF5, 0x16,
-       0x7B, 0x01, 0x7A, 0x01, 0x79, 0xA0, 0x12, 0x2B,
-       0xED, 0x90, 0x81, 0xD1, 0x12, 0x45, 0x16, 0x90,
-       0x00, 0x0E, 0x12, 0x1F, 0xBD, 0x90, 0x01, 0xAE,
-       0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0x01, 0xCB,
-       0xE0, 0x64, 0x80, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
-       0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
-       0xE4, 0xFF, 0x90, 0x80, 0xD9, 0xE0, 0xFE, 0x90,
-       0x80, 0xD8, 0xE0, 0xFD, 0xB5, 0x06, 0x04, 0x7E,
-       0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x64, 0x01,
-       0x60, 0x32, 0x90, 0x01, 0xAF, 0xE0, 0x70, 0x13,
-       0xED, 0x75, 0xF0, 0x0F, 0xA4, 0x24, 0x42, 0xF9,
-       0x74, 0x80, 0x35, 0xF0, 0xFA, 0x7B, 0x01, 0x71,
-       0xB6, 0x7F, 0x01, 0xEF, 0x60, 0x16, 0x90, 0x80,
-       0xD8, 0xE0, 0x04, 0xF0, 0xE0, 0x7F, 0x00, 0xB4,
-       0x0A, 0x02, 0x7F, 0x01, 0xEF, 0x60, 0x05, 0xE4,
-       0x90, 0x80, 0xD8, 0xF0, 0xD0, 0xD0, 0x92, 0xAF,
-       0x22, 0x8F, 0x0D, 0x22, 0x8F, 0x0E, 0x22, 0x22,
-       0x90, 0x01, 0x34, 0xE0, 0x55, 0x3D, 0xF5, 0x41,
-       0xA3, 0xE0, 0x55, 0x3E, 0xF5, 0x42, 0xA3, 0xE0,
-       0x55, 0x3F, 0xF5, 0x43, 0xA3, 0xE0, 0x55, 0x40,
-       0xF5, 0x44, 0x90, 0x01, 0x34, 0xE5, 0x41, 0xF0,
-       0xA3, 0xE5, 0x42, 0xF0, 0xA3, 0xE5, 0x43, 0xF0,
-       0xA3, 0xE5, 0x44, 0xF0, 0x22, 0x90, 0x01, 0x3C,
-       0xE0, 0x55, 0x45, 0xF5, 0x49, 0xA3, 0xE0, 0x55,
-       0x46, 0xF5, 0x4A, 0xA3, 0xE0, 0x55, 0x47, 0xF5,
-       0x4B, 0xA3, 0xE0, 0x55, 0x48, 0xF5, 0x4C, 0x90,
-       0x01, 0x3C, 0xE5, 0x49, 0xF0, 0xA3, 0xE5, 0x4A,
-       0xF0, 0xA3, 0xE5, 0x4B, 0xF0, 0xA3, 0xE5, 0x4C,
-       0xF0, 0x53, 0x91, 0xDF, 0x22, 0x90, 0x81, 0x1F,
-       0xE0, 0x30, 0xE0, 0x05, 0xE4, 0xA3, 0xF0, 0xA3,
-       0xF0, 0x22, 0x90, 0x80, 0xDE, 0xE0, 0x64, 0x01,
-       0x70, 0x19, 0x90, 0x81, 0x27, 0xE0, 0x60, 0x13,
-       0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90, 0x01, 0x3C,
-       0x74, 0x02, 0x12, 0x4F, 0xF4, 0x90, 0x01, 0x57,
-       0x74, 0x05, 0xF0, 0x22, 0x90, 0x80, 0xDE, 0xE0,
-       0x64, 0x01, 0x70, 0x26, 0x90, 0x81, 0x27, 0xE0,
-       0x60, 0x20, 0x90, 0x01, 0x57, 0xE4, 0xF0, 0x90,
-       0x01, 0x3C, 0x74, 0x02, 0xF0, 0x90, 0x81, 0x24,
-       0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x81, 0x2B, 0xE0,
-       0x54, 0xFD, 0xF0, 0x54, 0x07, 0x70, 0x03, 0x12,
-       0x47, 0x2A, 0x22, 0x90, 0x80, 0xDE, 0xE0, 0xB4,
-       0x01, 0x14, 0x90, 0x81, 0x27, 0xE0, 0x60, 0x0E,
-       0x90, 0x81, 0x26, 0xE0, 0x54, 0x0F, 0x64, 0x02,
-       0x60, 0x02, 0x80, 0x03, 0xD1, 0x7F, 0x22, 0x90,
-       0x04, 0x1D, 0xE0, 0x70, 0x13, 0x90, 0x80, 0x3E,
-       0xE0, 0xFF, 0xE4, 0xFD, 0xB1, 0x69, 0x8E, 0x4E,
-       0x8F, 0x4F, 0x90, 0x04, 0x1F, 0x74, 0x20, 0xF0,
-       0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0,
-       0x90, 0x82, 0x0E, 0xED, 0xF0, 0x90, 0x82, 0x0D,
-       0xEF, 0xF0, 0xE4, 0xFD, 0xFC, 0xF1, 0x37, 0x7C,
-       0x00, 0xAD, 0x07, 0x90, 0x82, 0x0D, 0xE0, 0x90,
-       0x04, 0x25, 0xF0, 0x90, 0x82, 0x0E, 0xE0, 0x60,
-       0x0E, 0x74, 0x0F, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
-       0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0xAF,
-       0x05, 0x74, 0x08, 0x2F, 0xF5, 0x82, 0xE4, 0x34,
-       0xFC, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x09, 0x2F,
-       0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
-       0x54, 0xF0, 0xF0, 0x74, 0x21, 0x2D, 0xF5, 0x82,
-       0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x54, 0xF7,
-       0xF0, 0xAE, 0x04, 0xAF, 0x05, 0xD0, 0xD0, 0x92,
-       0xAF, 0x22, 0x8F, 0x4E, 0xF1, 0x4B, 0xBF, 0x01,
-       0x18, 0x90, 0x80, 0x40, 0xE0, 0xFF, 0x7D, 0x01,
-       0xB1, 0x69, 0xAD, 0x07, 0xAC, 0x06, 0xAF, 0x4E,
-       0x12, 0x4F, 0x82, 0x90, 0x04, 0x1F, 0x74, 0x20,
-       0xF0, 0x22, 0x90, 0x06, 0xA9, 0xE0, 0x90, 0x81,
-       0x4C, 0xF0, 0xE0, 0xFD, 0x54, 0xC0, 0x70, 0x09,
-       0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFE, 0xF0, 0x80,
-       0x72, 0xED, 0x30, 0xE6, 0x4B, 0x90, 0x81, 0x27,
-       0xE0, 0x64, 0x02, 0x70, 0x2A, 0x90, 0x81, 0x24,
-       0xE0, 0xFF, 0xC3, 0x13, 0x20, 0xE0, 0x09, 0x90,
-       0x81, 0x2B, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x28,
-       0x90, 0x81, 0x26, 0xE0, 0x54, 0x0F, 0x64, 0x01,
-       0x70, 0x2D, 0x90, 0x81, 0x2B, 0xE0, 0x44, 0x04,
-       0xF0, 0x7F, 0x01, 0xB1, 0xD2, 0x80, 0x20, 0x90,
-       0x81, 0x2B, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x81,
-       0x26, 0xE0, 0x54, 0x0F, 0x64, 0x02, 0x60, 0x04,
-       0xB1, 0x4F, 0x80, 0x0B, 0xD1, 0x7F, 0x80, 0x07,
-       0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFE, 0xF0, 0x90,
-       0x81, 0x4C, 0xE0, 0x90, 0x81, 0x2B, 0x30, 0xE7,
-       0x11, 0x12, 0x4F, 0xF1, 0x90, 0x01, 0x57, 0x74,
-       0x05, 0xF0, 0x90, 0x81, 0x24, 0xE0, 0x44, 0x04,
-       0xF0, 0x22, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90,
-       0x01, 0x5F, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74,
-       0x08, 0xF0, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x3A,
-       0xE0, 0xC3, 0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4,
-       0xFB, 0xFD, 0x7F, 0x5C, 0x7E, 0x01, 0x12, 0x50,
-       0x05, 0x90, 0x01, 0x5F, 0x74, 0x05, 0xF0, 0x90,
-       0x06, 0x92, 0x74, 0x02, 0xF0, 0x90, 0x81, 0x24,
-       0xE0, 0x44, 0x10, 0xF0, 0x90, 0x81, 0x2A, 0xE0,
-       0x64, 0x0C, 0x60, 0x0C, 0xE4, 0xFD, 0x7F, 0x0C,
-       0x12, 0x47, 0x3D, 0xE4, 0xFF, 0x12, 0x4F, 0x0D,
-       0x22, 0xE4, 0x90, 0x81, 0x4C, 0xF0, 0x90, 0x06,
-       0xA9, 0xE0, 0x90, 0x81, 0x4C, 0xF0, 0xE0, 0x54,
-       0xC0, 0x70, 0x0D, 0x90, 0x81, 0x2B, 0xE0, 0x54,
-       0xFE, 0xF0, 0x54, 0xFD, 0xF0, 0x02, 0x47, 0x2A,
-       0x90, 0x81, 0x4C, 0xE0, 0x30, 0xE6, 0x21, 0x90,
-       0x81, 0x27, 0xE0, 0x64, 0x01, 0x70, 0x20, 0x90,
-       0x81, 0x2B, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0x81,
-       0x26, 0xE0, 0x54, 0x0F, 0x64, 0x02, 0x60, 0x04,
-       0xB1, 0x4F, 0x80, 0x0B, 0xD1, 0x7F, 0x80, 0x07,
-       0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFE, 0xF0, 0x90,
-       0x81, 0x4C, 0xE0, 0x90, 0x81, 0x2B, 0x30, 0xE7,
-       0x11, 0x12, 0x4F, 0xF1, 0x90, 0x01, 0x57, 0x74,
-       0x05, 0xF0, 0x90, 0x81, 0x24, 0xE0, 0x44, 0x04,
-       0xF0, 0x22, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0xE4,
-       0xFE, 0xEF, 0xC3, 0x13, 0xFD, 0xEF, 0x30, 0xE0,
-       0x02, 0x7E, 0x80, 0x90, 0xFD, 0x10, 0xED, 0xF0,
-       0xAF, 0x06, 0x22, 0xD3, 0x10, 0xAF, 0x01, 0xC3,
-       0xC0, 0xD0, 0x90, 0x04, 0x1D, 0xE0, 0x60, 0x1A,
-       0x90, 0x05, 0x22, 0xE0, 0x54, 0x90, 0x60, 0x07,
-       0x90, 0x01, 0xC0, 0xE0, 0x44, 0x08, 0xF0, 0x90,
-       0x01, 0xC6, 0xE0, 0x30, 0xE1, 0xE4, 0x7F, 0x00,
-       0x80, 0x02, 0x7F, 0x01, 0xD0, 0xD0, 0x92, 0xAF,
-       0x22, 0x90, 0x81, 0x27, 0xE0, 0x60, 0x03, 0x12,
-       0x73, 0xE1, 0x90, 0x81, 0x3F, 0xE0, 0x30, 0xE0,
-       0x03, 0x12, 0x49, 0xDD, 0x22, 0x90, 0x81, 0x27,
-       0xE0, 0x60, 0x35, 0x90, 0x06, 0x92, 0xE0, 0x30,
-       0xE1, 0x24, 0xE4, 0xF5, 0x1D, 0x90, 0x81, 0x3A,
-       0xE0, 0xC3, 0x13, 0x54, 0x7F, 0xF5, 0x1E, 0xE4,
-       0xFB, 0xFD, 0x7F, 0x5C, 0x7E, 0x01, 0x12, 0x50,
-       0x05, 0x90, 0x01, 0x5F, 0x74, 0x05, 0xF0, 0x90,
-       0x06, 0x92, 0x74, 0x02, 0xF0, 0x22, 0x90, 0x81,
-       0x24, 0xE0, 0x54, 0xEF, 0xF0, 0x12, 0x47, 0x2A,
-       0x22, 0x12, 0x71, 0x48, 0x90, 0x81, 0x4D, 0xEF,
-       0xF0, 0x90, 0x81, 0x24, 0x30, 0xE0, 0x06, 0xE0,
-       0x44, 0x01, 0xF0, 0x80, 0x04, 0xE0, 0x54, 0xFE,
-       0xF0, 0x90, 0x81, 0x4D, 0xE0, 0x30, 0xE6, 0x11,
-       0x90, 0x01, 0x2F, 0xE0, 0x30, 0xE7, 0x04, 0xE4,
-       0xF0, 0x80, 0x06, 0x90, 0x01, 0x2F, 0x74, 0x80,
-       0xF0, 0x90, 0x81, 0x24, 0xE0, 0x30, 0xE0, 0x1A,
-       0x90, 0x81, 0x32, 0xE4, 0xF0, 0xA3, 0x74, 0x07,
-       0xF0, 0x90, 0x81, 0x32, 0xA3, 0xE0, 0x90, 0x05,
-       0x58, 0xF0, 0x90, 0x04, 0xEC, 0xE0, 0x54, 0xDD,
-       0xF0, 0x22, 0x90, 0x04, 0xEC, 0xE0, 0x44, 0x22,
-       0xF0, 0x22, 0x90, 0x81, 0x4A, 0xE0, 0x60, 0x0F,
-       0xE4, 0xF0, 0x90, 0x05, 0x53, 0xE0, 0x44, 0x01,
-       0xF0, 0x90, 0x05, 0xFD, 0xE0, 0x04, 0xF0, 0x22,
-       0x90, 0x81, 0x24, 0xE0, 0xFF, 0xC4, 0x13, 0x13,
-       0x54, 0x03, 0x30, 0xE0, 0x27, 0xEF, 0x54, 0xBF,
-       0xF0, 0x90, 0x04, 0xE0, 0xE0, 0x90, 0x81, 0x25,
-       0x30, 0xE0, 0x06, 0xE0, 0x44, 0x01, 0xF0, 0x80,
-       0x10, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x01, 0xB9,
-       0x74, 0x01, 0xF0, 0x90, 0x01, 0xB8, 0x74, 0x04,
-       0xF0, 0x12, 0x47, 0x2A, 0xE4, 0xFF, 0x90, 0x81,
-       0x45, 0xE0, 0x30, 0xE0, 0x48, 0x90, 0x81, 0x49,
-       0xE0, 0xFD, 0x60, 0x41, 0x74, 0x01, 0x7E, 0x00,
-       0xA8, 0x07, 0x08, 0x80, 0x05, 0xC3, 0x33, 0xCE,
-       0x33, 0xCE, 0xD8, 0xF9, 0xFF, 0x90, 0x04, 0xE0,
-       0xE0, 0xFB, 0xEF, 0x5B, 0x60, 0x06, 0xE4, 0x90,
-       0x81, 0x49, 0xF0, 0x22, 0x90, 0x81, 0x47, 0xE0,
-       0xD3, 0x9D, 0x50, 0x10, 0x90, 0x01, 0xC7, 0x74,
-       0x10, 0xF0, 0x11, 0xBE, 0x90, 0x81, 0x45, 0xE0,
-       0x54, 0xFE, 0xF0, 0x22, 0x12, 0x4F, 0x0B, 0x90,
-       0x81, 0x49, 0xE0, 0x04, 0xF0, 0x22, 0x90, 0x80,
-       0x3C, 0xE0, 0x64, 0x02, 0x60, 0x07, 0x90, 0x06,
-       0x90, 0xE0, 0x44, 0x01, 0xF0, 0x22, 0x90, 0x81,
-       0x24, 0xE0, 0xFF, 0xC4, 0x13, 0x13, 0x13, 0x54,
-       0x01, 0x30, 0xE0, 0x2C, 0xEF, 0x54, 0x7F, 0xF0,
-       0x90, 0x04, 0xE0, 0xE0, 0x90, 0x81, 0x25, 0x30,
-       0xE1, 0x06, 0xE0, 0x44, 0x02, 0xF0, 0x80, 0x0F,
-       0xE0, 0x54, 0xFD, 0xF0, 0x90, 0x01, 0xB9, 0x74,
-       0x01, 0xF0, 0x90, 0x01, 0xB8, 0x04, 0xF0, 0x90,
-       0x81, 0x27, 0xE0, 0x60, 0x03, 0x12, 0x47, 0x2A,
-       0x7F, 0x01, 0x01, 0x6E, 0xC3, 0xEE, 0x94, 0x01,
-       0x40, 0x0A, 0x0D, 0xED, 0x13, 0x90, 0xFD, 0x10,
-       0xF0, 0xE4, 0x2F, 0xFF, 0x22, 0xC3, 0xEE, 0x94,
-       0x01, 0x40, 0x24, 0x90, 0xFD, 0x11, 0xE0, 0x6D,
-       0x70, 0x1A, 0x90, 0x01, 0x17, 0xE0, 0xB5, 0x05,
-       0x0D, 0x90, 0x01, 0xE4, 0x74, 0x77, 0xF0, 0x90,
-       0xFD, 0x11, 0xE4, 0xF0, 0x80, 0x06, 0xED, 0x04,
-       0x90, 0xFD, 0x11, 0xF0, 0xE4, 0x2F, 0xFF, 0x22,
-       0xE4, 0x90, 0x81, 0x4E, 0xF0, 0xA3, 0xF0, 0xA3,
-       0xF0, 0x90, 0x00, 0x83, 0xE0, 0x90, 0x81, 0x4E,
-       0xF0, 0x90, 0x00, 0x83, 0xE0, 0xFE, 0x90, 0x81,
-       0x4E, 0xE0, 0xFF, 0xB5, 0x06, 0x01, 0x22, 0xC3,
-       0x90, 0x81, 0x50, 0xE0, 0x94, 0x64, 0x90, 0x81,
-       0x4F, 0xE0, 0x94, 0x00, 0x40, 0x0D, 0x90, 0x01,
-       0xC0, 0xE0, 0x44, 0x40, 0xF0, 0x90, 0x81, 0x4E,
-       0xE0, 0xFF, 0x22, 0x90, 0x81, 0x4F, 0xE4, 0x75,
-       0xF0, 0x01, 0x12, 0x44, 0xA9, 0x80, 0xC2, 0x74,
-       0x45, 0x2F, 0xF8, 0xE6, 0xFE, 0xED, 0xF4, 0x5E,
-       0xFE, 0xF6, 0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4,
-       0x34, 0x01, 0xF5, 0x83, 0xEE, 0xF0, 0x22, 0xD3,
-       0x10, 0xAF, 0x01, 0xC3, 0xC0, 0xD0, 0x90, 0x82,
-       0x12, 0xED, 0xF0, 0x90, 0x82, 0x11, 0xEF, 0xF0,
-       0xD3, 0x94, 0x07, 0x50, 0x70, 0xE0, 0xFF, 0x74,
-       0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33,
-       0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x47, 0xE0,
-       0x5F, 0xFD, 0x7F, 0x47, 0x12, 0x32, 0x1E, 0x90,
-       0x82, 0x11, 0xE0, 0xFF, 0x74, 0x01, 0xA8, 0x07,
-       0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC, 0xFF,
-       0x90, 0x00, 0x46, 0xE0, 0x4F, 0xFD, 0x7F, 0x46,
-       0x12, 0x32, 0x1E, 0x90, 0x82, 0x12, 0xE0, 0x60,
-       0x18, 0x90, 0x82, 0x11, 0xE0, 0xFF, 0x74, 0x01,
-       0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
-       0xFC, 0xFF, 0x90, 0x00, 0x45, 0xE0, 0x4F, 0x80,
-       0x17, 0x90, 0x82, 0x11, 0xE0, 0xFF, 0x74, 0x01,
-       0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
-       0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x45, 0xE0, 0x5F,
-       0xFD, 0x7F, 0x45, 0x80, 0x7E, 0x90, 0x82, 0x11,
-       0xE0, 0x24, 0xF8, 0xF0, 0xE0, 0x24, 0x04, 0xFF,
-       0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3,
-       0x33, 0xD8, 0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x43,
-       0xE0, 0x5F, 0xFD, 0x7F, 0x43, 0x12, 0x32, 0x1E,
-       0x90, 0x82, 0x11, 0xE0, 0xFF, 0x74, 0x01, 0xA8,
-       0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8, 0xFC,
-       0xFF, 0x90, 0x00, 0x43, 0xE0, 0x4F, 0xFD, 0x7F,
-       0x43, 0x12, 0x32, 0x1E, 0x90, 0x82, 0x12, 0xE0,
-       0x60, 0x1D, 0x90, 0x82, 0x11, 0xE0, 0x24, 0x04,
-       0xFF, 0x74, 0x01, 0xA8, 0x07, 0x08, 0x80, 0x02,
-       0xC3, 0x33, 0xD8, 0xFC, 0xFF, 0x90, 0x00, 0x42,
-       0xE0, 0x4F, 0xFD, 0x7F, 0x42, 0x80, 0x1C, 0x90,
-       0x82, 0x11, 0xE0, 0x24, 0x04, 0xFF, 0x74, 0x01,
-       0xA8, 0x07, 0x08, 0x80, 0x02, 0xC3, 0x33, 0xD8,
-       0xFC, 0xF4, 0xFF, 0x90, 0x00, 0x42, 0xE0, 0x5F,
-       0xFD, 0x7F, 0x42, 0x12, 0x32, 0x1E, 0xD0, 0xD0,
-       0x92, 0xAF, 0x22, 0x90, 0x81, 0x24, 0xE0, 0x54,
-       0xFB, 0xF0, 0xE4, 0x90, 0x81, 0x30, 0xF0, 0x90,
-       0x81, 0x2B, 0xF0, 0x22, 0xEF, 0x24, 0xFE, 0x60,
-       0x0C, 0x04, 0x70, 0x28, 0x90, 0x81, 0x2D, 0x74,
-       0x01, 0xF0, 0xA3, 0xF0, 0x22, 0xED, 0x70, 0x0A,
-       0x90, 0x81, 0x3B, 0xE0, 0x90, 0x81, 0x2D, 0xF0,
-       0x80, 0x05, 0x90, 0x81, 0x2D, 0xED, 0xF0, 0x90,
-       0x81, 0x2D, 0xE0, 0xA3, 0xF0, 0x90, 0x81, 0x25,
-       0xE0, 0x44, 0x08, 0xF0, 0x22, 0x12, 0x4E, 0xAB,
-       0xEF, 0x64, 0x01, 0x60, 0x08, 0x90, 0x01, 0xB8,
-       0x74, 0x01, 0xF0, 0x80, 0x67, 0x90, 0x81, 0x2B,
-       0xE0, 0xFF, 0x54, 0x03, 0x60, 0x08, 0x90, 0x01,
-       0xB8, 0x74, 0x02, 0xF0, 0x80, 0x56, 0x90, 0x81,
-       0x29, 0xE0, 0xFE, 0xE4, 0xC3, 0x9E, 0x50, 0x08,
-       0x90, 0x01, 0xB8, 0x74, 0x04, 0xF0, 0x80, 0x44,
-       0xEF, 0x30, 0xE2, 0x08, 0x90, 0x01, 0xB8, 0x74,
-       0x08, 0xF0, 0x80, 0x38, 0x90, 0x81, 0x2B, 0xE0,
-       0x30, 0xE4, 0x08, 0x90, 0x01, 0xB8, 0x74, 0x10,
-       0xF0, 0x80, 0x29, 0x90, 0x81, 0x25, 0xE0, 0x13,
-       0x13, 0x54, 0x3F, 0x20, 0xE0, 0x08, 0x90, 0x01,
-       0xB8, 0x74, 0x20, 0xF0, 0x80, 0x16, 0x90, 0x81,
-       0x3E, 0xE0, 0x60, 0x08, 0x90, 0x01, 0xB8, 0x74,
-       0x80, 0xF0, 0x80, 0x08, 0x90, 0x01, 0xB8, 0xE4,
-       0xF0, 0x7F, 0x01, 0x22, 0x90, 0x01, 0xB9, 0x74,
-       0x04, 0xF0, 0x7F, 0x00, 0x22, 0xEF, 0x60, 0x42,
-       0x90, 0x80, 0xDE, 0xE0, 0x64, 0x01, 0x70, 0x3A,
-       0x90, 0x81, 0x25, 0xE0, 0x54, 0xFE, 0xF0, 0x90,
-       0x05, 0x22, 0x74, 0x0F, 0xF0, 0x90, 0x06, 0x04,
-       0xE0, 0x54, 0xBF, 0xF0, 0xE4, 0xFF, 0x12, 0x4F,
-       0x0D, 0xBF, 0x01, 0x12, 0x90, 0x81, 0x24, 0xE0,
-       0x44, 0x40, 0xF0, 0x90, 0x81, 0x2A, 0x74, 0x06,
-       0xF0, 0x90, 0x81, 0x23, 0xF0, 0x22, 0x90, 0x01,
-       0xB9, 0x74, 0x01, 0xF0, 0x90, 0x01, 0xB8, 0x74,
-       0x08, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0x6F,
-       0xF0, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0,
-       0x90, 0x81, 0x2A, 0x74, 0x02, 0xF0, 0x90, 0x81,
-       0x23, 0xF0, 0x22, 0x12, 0x54, 0x65, 0x90, 0x81,
-       0x2A, 0x74, 0x0C, 0xF0, 0x90, 0x81, 0x23, 0xF0,
-       0x22, 0x90, 0x81, 0x24, 0xE0, 0xFF, 0x13, 0x13,
-       0x54, 0x3F, 0x30, 0xE0, 0x11, 0xEF, 0x54, 0xFB,
-       0xF0, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFD, 0xF0,
-       0x54, 0x07, 0x70, 0x42, 0x80, 0x3D, 0x90, 0x81,
-       0x30, 0xE0, 0x04, 0xF0, 0x90, 0x81, 0x2B, 0xE0,
-       0x54, 0xEF, 0xF0, 0x90, 0x81, 0x30, 0xE0, 0xFF,
-       0xB4, 0x01, 0x02, 0x80, 0x04, 0xEF, 0xB4, 0x02,
-       0x06, 0x90, 0x05, 0x58, 0xE0, 0x04, 0xF0, 0x90,
-       0x81, 0x38, 0xE0, 0xFF, 0x90, 0x81, 0x30, 0xE0,
-       0xD3, 0x9F, 0x40, 0x0F, 0x90, 0x80, 0xDE, 0xE0,
-       0xB4, 0x01, 0x0B, 0x90, 0x81, 0x25, 0xE0, 0x54,
-       0xFB, 0xF0, 0x22, 0x12, 0x47, 0x2A, 0x22, 0x22,
-       0x90, 0x05, 0x2B, 0xE0, 0x7F, 0x00, 0x30, 0xE7,
-       0x02, 0x7F, 0x01, 0x22, 0x90, 0x05, 0x22, 0x74,
-       0xFF, 0xF0, 0x90, 0x05, 0x27, 0xE0, 0x44, 0x40,
-       0xF0, 0x90, 0x81, 0x22, 0x74, 0x03, 0xF0, 0x22,
-       0x90, 0x05, 0x27, 0xE0, 0x44, 0x40, 0xF0, 0x12,
-       0x49, 0xDD, 0x90, 0x81, 0x22, 0x74, 0x02, 0xF0,
-       0x22, 0x12, 0x49, 0xE3, 0x90, 0x81, 0x22, 0x74,
-       0x02, 0xF0, 0x22, 0x90, 0x05, 0x22, 0x74, 0x6F,
-       0xF0, 0x90, 0x05, 0x27, 0xE0, 0x54, 0xBF, 0xF0,
-       0x90, 0x81, 0x22, 0x74, 0x04, 0xF0, 0x22, 0xAE,
-       0x07, 0x12, 0x51, 0x73, 0xBF, 0x01, 0x12, 0x90,
-       0x81, 0x23, 0xE0, 0x64, 0x02, 0x60, 0x0A, 0xAF,
-       0x06, 0x7D, 0x01, 0x12, 0x47, 0x3D, 0x7F, 0x01,
-       0x22, 0x7F, 0x00, 0x22, 0x90, 0x01, 0x57, 0xE0,
-       0x60, 0x48, 0xE4, 0xF0, 0x90, 0x01, 0x3C, 0x74,
-       0x02, 0xF0, 0x90, 0x81, 0x24, 0xE0, 0xFF, 0x13,
-       0x13, 0x54, 0x3F, 0x30, 0xE0, 0x0C, 0xEF, 0x54,
-       0xFB, 0xF0, 0x90, 0x81, 0x2B, 0xE0, 0x54, 0xFD,
-       0xF0, 0x22, 0x90, 0x81, 0x30, 0xE0, 0x04, 0xF0,
-       0x90, 0x81, 0x2B, 0xE0, 0x54, 0xEF, 0xF0, 0x90,
-       0x81, 0x38, 0xE0, 0xFF, 0x90, 0x81, 0x30, 0xE0,
-       0xD3, 0x9F, 0x40, 0x0E, 0x90, 0x80, 0xDE, 0xE0,
-       0xB4, 0x01, 0x07, 0x90, 0x81, 0x25, 0xE0, 0x54,
-       0xFB, 0xF0, 0x22, 0x90, 0x80, 0x3F, 0xE0, 0xFF,
-       0x7D, 0x01, 0x12, 0x6D, 0x69, 0x8E, 0x54, 0x8F,
-       0x55, 0xAD, 0x55, 0xAC, 0x54, 0xAF, 0x53, 0x12,
-       0x4F, 0x82, 0xAF, 0x55, 0xAE, 0x54, 0x90, 0x04,
-       0x80, 0xE0, 0x54, 0x0F, 0xFD, 0xAC, 0x07, 0x74,
-       0x11, 0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5,
-       0x83, 0xE0, 0x44, 0x01, 0xF0, 0x74, 0x11, 0x2C,
-       0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
-       0x54, 0xFB, 0xF0, 0xAC, 0x07, 0x74, 0x16, 0x2C,
-       0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0,
-       0x44, 0xFA, 0xF0, 0x74, 0x15, 0x2C, 0xF5, 0x82,
-       0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x1F,
-       0xF0, 0xAC, 0x07, 0x74, 0x06, 0x2C, 0xF5, 0x82,
-       0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xE0, 0x44, 0x0F,
-       0xF0, 0x90, 0x04, 0x53, 0xE4, 0xF0, 0x90, 0x04,
-       0x52, 0xF0, 0x90, 0x04, 0x51, 0x74, 0xFF, 0xF0,
-       0x90, 0x04, 0x50, 0x74, 0xFD, 0xF0, 0x74, 0x14,
-       0x2C, 0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83,
-       0xE0, 0x54, 0xC0, 0x4D, 0xFD, 0x74, 0x14, 0x2F,
-       0xF5, 0x82, 0xE4, 0x34, 0xFC, 0xF5, 0x83, 0xED,
-       0xF0, 0x22, 0xAB, 0x07, 0xAA, 0x06, 0xED, 0x2B,
-       0xFB, 0xE4, 0x3A, 0xFA, 0xC3, 0x90, 0x80, 0xDB,
-       0xE0, 0x9B, 0x90, 0x80, 0xDA, 0xE0, 0x9A, 0x50,
-       0x13, 0xA3, 0xE0, 0x24, 0x01, 0xFF, 0x90, 0x80,
-       0xDA, 0xE0, 0x34, 0x00, 0xFE, 0xC3, 0xEB, 0x9F,
-       0xFB, 0xEA, 0x9E, 0xFA, 0xEA, 0x90, 0xFD, 0x11,
-       0xF0, 0xAF, 0x03, 0x74, 0x00, 0x2F, 0xF5, 0x82,
-       0xE4, 0x34, 0xFB, 0xF5, 0x83, 0xE0, 0xFF, 0x22,
-       0x12, 0x1F, 0xA4, 0xFF, 0x54, 0x01, 0xFE, 0x90,
-       0x81, 0x42, 0xE0, 0x54, 0xFE, 0x4E, 0xF0, 0xEF,
-       0xC3, 0x13, 0x30, 0xE0, 0x0A, 0x90, 0x00, 0x01,
-       0x12, 0x1F, 0xBD, 0x90, 0x81, 0x43, 0xF0, 0x22,
-       0x90, 0x81, 0x45, 0xE0, 0x30, 0xE0, 0x2D, 0x90,
-       0x81, 0x48, 0xE0, 0x04, 0xF0, 0xE0, 0xFF, 0x90,
-       0x81, 0x46, 0xE0, 0xB5, 0x07, 0x1E, 0x90, 0x06,
-       0x92, 0xE0, 0x54, 0x1C, 0x70, 0x0B, 0x12, 0x4F,
-       0x0B, 0x90, 0x81, 0x49, 0xE0, 0x04, 0xF0, 0x80,
-       0x06, 0x90, 0x06, 0x92, 0x74, 0x1C, 0xF0, 0xE4,
-       0x90, 0x81, 0x48, 0xF0, 0x22, 0x00, 0xBB, 0x8E,
-};
index e4f20da91b433de32c29ec5d21343cc464b7d3a6..bb43793fd1ec2f57ff6eb1d6019189957b9ed188 100644 (file)
@@ -1276,407 +1276,6 @@ static void phy_LCCalibrate_8188E(struct adapter *adapt, bool is2t)
        }
 }
 
-/* Analog Pre-distortion calibration */
-#define                APK_BB_REG_NUM  8
-#define                APK_CURVE_REG_NUM 4
-#define                PATH_NUM                2
-
-static void phy_APCalibrate_8188E(struct adapter *adapt, s8 delta, bool is2t)
-{
-       struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
-       struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
-       u32 regD[PATH_NUM];
-       u32 tmpreg, index, offset,  apkbound;
-       u8 path, i, pathbound = PATH_NUM;
-       u32 BB_backup[APK_BB_REG_NUM];
-       u32 BB_REG[APK_BB_REG_NUM] = {
-               rFPGA1_TxBlock,         rOFDM0_TRxPathEnable,
-               rFPGA0_RFMOD, rOFDM0_TRMuxPar,
-               rFPGA0_XCD_RFInterfaceSW, rFPGA0_XAB_RFInterfaceSW,
-               rFPGA0_XA_RFInterfaceOE, rFPGA0_XB_RFInterfaceOE        };
-       u32 BB_AP_MODE[APK_BB_REG_NUM] = {
-               0x00000020, 0x00a05430, 0x02040000,
-               0x000800e4, 0x00204000 };
-       u32 BB_normal_AP_MODE[APK_BB_REG_NUM] = {
-               0x00000020, 0x00a05430, 0x02040000,
-               0x000800e4, 0x22204000 };
-
-       u32 AFE_backup[IQK_ADDA_REG_NUM];
-       u32 AFE_REG[IQK_ADDA_REG_NUM] = {
-               rFPGA0_XCD_SwitchControl, rBlue_Tooth,
-               rRx_Wait_CCA,   rTx_CCK_RFON,
-               rTx_CCK_BBON, rTx_OFDM_RFON,
-               rTx_OFDM_BBON, rTx_To_Rx,
-               rTx_To_Tx,      rRx_CCK,
-               rRx_OFDM,       rRx_Wait_RIFS,
-               rRx_TO_Rx,      rStandby,
-               rSleep,                         rPMPD_ANAEN };
-
-       u32 MAC_backup[IQK_MAC_REG_NUM];
-       u32 MAC_REG[IQK_MAC_REG_NUM] = {
-               REG_TXPAUSE,    REG_BCN_CTRL,
-               REG_BCN_CTRL_1, REG_GPIO_MUXCFG};
-
-       u32 APK_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {
-               {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
-               {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}
-       };
-
-       u32 APK_normal_RF_init_value[PATH_NUM][APK_BB_REG_NUM] = {
-               {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, /* path settings equal to path b settings */
-               {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c}
-       };
-
-       u32 APK_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = {
-               {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
-               {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}
-       };
-
-       u32 APK_normal_RF_value_0[PATH_NUM][APK_BB_REG_NUM] = {
-               {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, /* path settings equal to path b settings */
-               {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}
-       };
-
-       u32 AFE_on_off[PATH_NUM] = {
-               0x04db25a4, 0x0b1b25a4};        /* path A on path B off / path A off path B on */
-
-       u32 APK_offset[PATH_NUM] = {
-               rConfig_AntA, rConfig_AntB};
-
-       u32 APK_normal_offset[PATH_NUM] = {
-               rConfig_Pmpd_AntA, rConfig_Pmpd_AntB};
-
-       u32 APK_value[PATH_NUM] = {
-               0x92fc0000, 0x12fc0000};
-
-       u32 APK_normal_value[PATH_NUM] = {
-               0x92680000, 0x12680000};
-
-       s8 APK_delta_mapping[APK_BB_REG_NUM][13] = {
-               {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
-               {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
-               {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
-               {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
-               {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}
-       };
-
-       u32 APK_normal_setting_value_1[13] = {
-               0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
-               0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
-               0x12680000, 0x00880000, 0x00880000
-       };
-
-       u32 APK_normal_setting_value_2[16] = {
-               0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
-               0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
-               0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
-               0x00050006
-       };
-
-       u32 APK_result[PATH_NUM][APK_BB_REG_NUM];       /* val_1_1a, val_1_2a, val_2a, val_3a, val_4a */
-       s32 BB_offset, delta_V, delta_offset;
-
-       if (*(dm_odm->mp_mode) == 1) {
-               struct mpt_context *pMptCtx = &(adapt->mppriv.MptCtx);
-               pMptCtx->APK_bound[0] = 45;
-               pMptCtx->APK_bound[1] = 52;
-       }
-
-       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("==>phy_APCalibrate_8188E() delta %d\n", delta));
-       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("AP Calibration for %s\n", (is2t ? "2T2R" : "1T1R")));
-       if (!is2t)
-               pathbound = 1;
-
-       /* 2 FOR NORMAL CHIP SETTINGS */
-
-/*  Temporarily do not allow normal driver to do the following settings
- *  because these offset and value will cause RF internal PA to be
- *  unpredictably disabled by HW, such that RF Tx signal  will disappear
- *  after disable/enable card many times on 88CU. RF SD and DD have not
- *  find the root cause, so we remove these actions temporarily.
- */
-       if (*(dm_odm->mp_mode) != 1)
-               return;
-       /* settings adjust for normal chip */
-       for (index = 0; index < PATH_NUM; index++) {
-               APK_offset[index] = APK_normal_offset[index];
-               APK_value[index] = APK_normal_value[index];
-               AFE_on_off[index] = 0x6fdb25a4;
-       }
-
-       for (index = 0; index < APK_BB_REG_NUM; index++) {
-               for (path = 0; path < pathbound; path++) {
-                       APK_RF_init_value[path][index] = APK_normal_RF_init_value[path][index];
-                       APK_RF_value_0[path][index] = APK_normal_RF_value_0[path][index];
-               }
-               BB_AP_MODE[index] = BB_normal_AP_MODE[index];
-       }
-
-       apkbound = 6;
-
-       /* save BB default value */
-       for (index = 0; index < APK_BB_REG_NUM; index++) {
-               if (index == 0)         /* skip */
-                       continue;
-               BB_backup[index] = ODM_GetBBReg(dm_odm, BB_REG[index], bMaskDWord);
-       }
-
-       /* save MAC default value */
-       _PHY_SaveMACRegisters(adapt, MAC_REG, MAC_backup);
-
-       /* save AFE default value */
-       _PHY_SaveADDARegisters(adapt, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
-
-       for (path = 0; path < pathbound; path++) {
-               if (path == RF_PATH_A) {
-                       /* path A APK */
-                       /* load APK setting */
-                       /* path-A */
-                       offset = rPdp_AntA;
-                       for (index = 0; index < 11; index++) {
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-                               offset += 0x04;
-                       }
-
-                       ODM_SetBBReg(dm_odm, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000);
-
-                       offset = rConfig_AntA;
-                       for (; index < 13; index++) {
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-                               offset += 0x04;
-                       }
-
-                       /* page-B1 */
-                       ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x40000000);
-
-                       /* path A */
-                       offset = rPdp_AntA;
-                       for (index = 0; index < 16; index++) {
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_2[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-
-                               offset += 0x04;
-                       }
-                       ODM_SetBBReg(dm_odm,  rFPGA0_IQK, bMaskDWord, 0x00000000);
-               } else if (path == RF_PATH_B) {
-                       /* path B APK */
-                       /* load APK setting */
-                       /* path-B */
-                       offset = rPdp_AntB;
-                       for (index = 0; index < 10; index++) {
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-
-                               offset += 0x04;
-                       }
-                       ODM_SetBBReg(dm_odm, rConfig_Pmpd_AntA, bMaskDWord, 0x12680000);
-                       PHY_SetBBReg(adapt, rConfig_Pmpd_AntB, bMaskDWord, 0x12680000);
-
-                       offset = rConfig_AntA;
-                       index = 11;
-                       for (; index < 13; index++) { /* offset 0xb68, 0xb6c */
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_1[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-                               offset += 0x04;
-                       }
-
-                       /* page-B1 */
-                       ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x40000000);
-
-                       /* path B */
-                       offset = 0xb60;
-                       for (index = 0; index < 16; index++) {
-                               ODM_SetBBReg(dm_odm, offset, bMaskDWord, APK_normal_setting_value_2[index]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n",
-                                            offset, ODM_GetBBReg(dm_odm, offset, bMaskDWord)));
-
-                               offset += 0x04;
-                       }
-                       ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0);
-               }
-
-               /* save RF default value */
-               regD[path] = PHY_QueryRFReg(adapt, path, RF_TXBIAS_A, bMaskDWord);
-
-               /* Path A AFE all on, path B AFE All off or vise versa */
-               for (index = 0; index < IQK_ADDA_REG_NUM; index++)
-                       ODM_SetBBReg(dm_odm, AFE_REG[index], bMaskDWord, AFE_on_off[path]);
-               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                            ("phy_APCalibrate_8188E() offset 0xe70 %x\n",
-                            ODM_GetBBReg(dm_odm, rRx_Wait_CCA, bMaskDWord)));
-
-               /* BB to AP mode */
-               if (path == 0) {
-                       for (index = 0; index < APK_BB_REG_NUM; index++) {
-                               if (index == 0)         /* skip */
-                                       continue;
-                               else if (index < 5)
-                               ODM_SetBBReg(dm_odm, BB_REG[index], bMaskDWord, BB_AP_MODE[index]);
-                               else if (BB_REG[index] == 0x870)
-                                       ODM_SetBBReg(dm_odm, BB_REG[index], bMaskDWord, BB_backup[index]|BIT10|BIT26);
-                               else
-                                       ODM_SetBBReg(dm_odm, BB_REG[index], BIT10, 0x0);
-                       }
-
-                       ODM_SetBBReg(dm_odm, rTx_IQK_Tone_A, bMaskDWord, 0x01008c00);
-                       ODM_SetBBReg(dm_odm, rRx_IQK_Tone_A, bMaskDWord, 0x01008c00);
-               } else {
-                       /* path B */
-                       ODM_SetBBReg(dm_odm, rTx_IQK_Tone_B, bMaskDWord, 0x01008c00);
-                       ODM_SetBBReg(dm_odm, rRx_IQK_Tone_B, bMaskDWord, 0x01008c00);
-               }
-
-               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                            ("phy_APCalibrate_8188E() offset 0x800 %x\n",
-                            ODM_GetBBReg(dm_odm, 0x800, bMaskDWord)));
-
-               /* MAC settings */
-               _PHY_MACSettingCalibration(adapt, MAC_REG, MAC_backup);
-
-               if (path == RF_PATH_A) {
-                       /* Path B to standby mode */
-                       ODM_SetRFReg(dm_odm, RF_PATH_B, RF_AC, bMaskDWord, 0x10000);
-               } else {
-                       /* Path A to standby mode */
-                       ODM_SetRFReg(dm_odm, RF_PATH_A, RF_AC, bMaskDWord, 0x10000);
-                       ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE1, bMaskDWord, 0x1000f);
-                       ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE2, bMaskDWord, 0x20103);
-               }
-
-               delta_offset = ((delta+14)/2);
-               if (delta_offset < 0)
-                       delta_offset = 0;
-               else if (delta_offset > 12)
-                       delta_offset = 12;
-
-               /* AP calibration */
-               for (index = 0; index < APK_BB_REG_NUM; index++) {
-                       if (index != 1) /* only DO PA11+PAD01001, AP RF setting */
-                               continue;
-
-                       tmpreg = APK_RF_init_value[path][index];
-                       if (!dm_odm->RFCalibrateInfo.bAPKThermalMeterIgnore) {
-                               BB_offset = (tmpreg & 0xF0000) >> 16;
-
-                               if (!(tmpreg & BIT15)) /* sign bit 0 */
-                                       BB_offset = -BB_offset;
-
-                               delta_V = APK_delta_mapping[index][delta_offset];
-
-                               BB_offset += delta_V;
-
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,
-                                            ("phy_APCalibrate_8188E() APK index %d tmpreg 0x%x delta_V %d delta_offset %d\n",
-                                            index, tmpreg, delta_V, delta_offset));
-
-                               if (BB_offset < 0) {
-                                       tmpreg = tmpreg & (~BIT15);
-                                       BB_offset = -BB_offset;
-                               } else {
-                                       tmpreg = tmpreg | BIT15;
-                               }
-                               tmpreg = (tmpreg & 0xFFF0FFFF) | (BB_offset << 16);
-                       }
-
-                       ODM_SetRFReg(dm_odm, path, RF_IPA_A, bMaskDWord, 0x8992e);
-                       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0xc %x\n", PHY_QueryRFReg(adapt, path, RF_IPA_A, bMaskDWord)));
-                       ODM_SetRFReg(dm_odm, path, RF_AC, bMaskDWord, APK_RF_value_0[path][index]);
-                       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("phy_APCalibrate_8188E() offset 0x0 %x\n", PHY_QueryRFReg(adapt, path, RF_AC, bMaskDWord)));
-                       ODM_SetRFReg(dm_odm, path, RF_TXBIAS_A, bMaskDWord, tmpreg);
-                       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0xd %x\n", PHY_QueryRFReg(adapt, path, RF_TXBIAS_A, bMaskDWord)));
-                       /*  PA11+PAD01111, one shot */
-                       i = 0;
-                       do {
-                               ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x80000000);
-                               ODM_SetBBReg(dm_odm, APK_offset[path], bMaskDWord, APK_value[0]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n", APK_offset[path], ODM_GetBBReg(dm_odm, APK_offset[path], bMaskDWord)));
-                               ODM_delay_ms(3);
-                               ODM_SetBBReg(dm_odm, APK_offset[path], bMaskDWord, APK_value[1]);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0x%x value 0x%x\n", APK_offset[path], ODM_GetBBReg(dm_odm, APK_offset[path], bMaskDWord)));
-
-                               ODM_delay_ms(20);
-                               ODM_SetBBReg(dm_odm, rFPGA0_IQK, bMaskDWord, 0x00000000);
-
-                               if (path == RF_PATH_A)
-                                       tmpreg = ODM_GetBBReg(dm_odm, rAPK, 0x03E00000);
-                               else
-                                       tmpreg = ODM_GetBBReg(dm_odm, rAPK, 0xF8000000);
-                               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("phy_APCalibrate_8188E() offset 0xbd8[25:21] %x\n", tmpreg));
-
-                               i++;
-                       } while (tmpreg > apkbound && i < 4);
-
-                       APK_result[path][index] = tmpreg;
-               }
-       }
-
-       /* reload MAC default value */
-       _PHY_ReloadMACRegisters(adapt, MAC_REG, MAC_backup);
-
-       /* reload BB default value */
-       for (index = 0; index < APK_BB_REG_NUM; index++) {
-               if (index == 0)         /* skip */
-                       continue;
-               ODM_SetBBReg(dm_odm, BB_REG[index], bMaskDWord, BB_backup[index]);
-       }
-
-       /* reload AFE default value */
-       reload_adda_reg(adapt, AFE_REG, AFE_backup, IQK_ADDA_REG_NUM);
-
-       /* reload RF path default value */
-       for (path = 0; path < pathbound; path++) {
-               ODM_SetRFReg(dm_odm, path, 0xd, bMaskDWord, regD[path]);
-               if (path == RF_PATH_B) {
-                       ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE1, bMaskDWord, 0x1000f);
-                       ODM_SetRFReg(dm_odm, RF_PATH_A, RF_MODE2, bMaskDWord, 0x20101);
-               }
-
-               /* note no index == 0 */
-               if (APK_result[path][1] > 6)
-                       APK_result[path][1] = 6;
-               ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("apk path %d result %d 0x%x \t", path, 1, APK_result[path][1]));
-       }
-
-       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD,  ("\n"));
-
-       for (path = 0; path < pathbound; path++) {
-               ODM_SetRFReg(dm_odm, path, 0x3, bMaskDWord,
-                            ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (APK_result[path][1] << 5) | APK_result[path][1]));
-               if (path == RF_PATH_A)
-                       ODM_SetRFReg(dm_odm, path, 0x4, bMaskDWord,
-                                    ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x00 << 5) | 0x05));
-               else
-                       ODM_SetRFReg(dm_odm, path, 0x4, bMaskDWord,
-                                    ((APK_result[path][1] << 15) | (APK_result[path][1] << 10) | (0x02 << 5) | 0x05));
-               ODM_SetRFReg(dm_odm, path, RF_BS_PA_APSET_G9_G11, bMaskDWord,
-                            ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | 0x08));
-       }
-
-       dm_odm->RFCalibrateInfo.bAPKdone = true;
-
-       ODM_RT_TRACE(dm_odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("<==phy_APCalibrate_8188E()\n"));
-}
-
-#define                DP_BB_REG_NUM           7
-#define                DP_RF_REG_NUM           1
-#define                DP_RETRY_LIMIT          10
-#define                DP_PATH_NUM             2
-#define                DP_DPK_NUM                      3
-#define                DP_DPK_VALUE_NUM        2
-
 void PHY_IQCalibrate_8188E(struct adapter *adapt, bool recovery)
 {
        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
@@ -1867,28 +1466,6 @@ void PHY_LCCalibrate_8188E(struct adapter *adapt)
                     ("LCK:Finish!!!interface %d\n", dm_odm->InterfaceIndex));
 }
 
-void PHY_APCalibrate_8188E(struct adapter *adapt, s8 delta)
-{
-       struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
-       struct odm_dm_struct *dm_odm = &pHalData->odmpriv;
-
-       return;
-       if (!(dm_odm->SupportAbility & ODM_RF_CALIBRATION))
-               return;
-
-#if FOR_BRAZIL_PRETEST != 1
-       if (dm_odm->RFCalibrateInfo.bAPKdone)
-#endif
-               return;
-
-       if (dm_odm->RFType == ODM_2T2R) {
-               phy_APCalibrate_8188E(adapt, delta, true);
-       } else {
-               /*  For 88C 1T1R */
-               phy_APCalibrate_8188E(adapt, delta, false);
-       }
-}
-
 static void phy_setrfpathswitch_8188e(struct adapter *adapt, bool main, bool is2t)
 {
        struct hal_data_8188e   *pHalData = GET_HAL_DATA(adapt);
index e913a22a6426af43c0332aea1835b775e0af5988..5700dbce5b8c54d00bafdb9839c7615b698bc157 100644 (file)
@@ -85,7 +85,7 @@ u8 HalPwrSeqCmdParsing(struct adapter *padapter, u8 cut_vers, u8 fab_vers,
                                value &= ~(GET_PWR_CFG_MASK(pwrcfgcmd));
                                value |= (GET_PWR_CFG_VALUE(pwrcfgcmd) & GET_PWR_CFG_MASK(pwrcfgcmd));
 
-                               /*  Write the value back to sytem register */
+                               /*  Write the value back to system register */
                                rtw_write8(padapter, offset, value);
                                break;
                        case PWR_CMD_POLLING:
index 8c8587754517f0ceda6249dd52bfe1a48e2a3798..0b0c68c9865c1ced91c3e2f07e1cdd347de31a23 100644 (file)
@@ -484,7 +484,7 @@ static void ConstructProbeRsp(struct adapter *adapt, u8 *pframe, u32 *pLength, u
        *pLength = pktlen;
 }
 
-/*  To check if reserved page content is destroyed by beacon beacuse beacon is too large. */
+/*  To check if reserved page content is destroyed by beacon because beacon is too large. */
 /*  2010.06.23. Added by tynli. */
 void CheckFwRsvdPageContent(struct adapter *Adapter)
 {
@@ -496,9 +496,9 @@ void CheckFwRsvdPageContent(struct adapter *Adapter)
 /*                     (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp. */
 /*     Input: */
 /*         bDLFinished - false: At the first time we will send all the packets as a large packet to Hw, */
-/*                                             so we need to set the packet length to total lengh. */
+/*                                             so we need to set the packet length to total length. */
 /*                           true: At the second time, we should send the first packet (default:beacon) */
-/*                                             to Hw again and set the lengh in descriptor to the real beacon lengh. */
+/*                                             to Hw again and set the length in descriptor to the real beacon length. */
 /*  2009.10.15 by tynli. */
 static void SetFwRsvdPagePkt(struct adapter *adapt, bool bDLFinished)
 {
@@ -671,7 +671,7 @@ _func_enter_;
                        DBG_88E("%s: 1 Download RSVD success! DLBcnCount:%u, poll:%u\n", __func__, DLBcnCount, poll);
                /*  */
                /*  We just can send the reserved page twice during the time that Tx thread is stopped (e.g. pnpsetpower) */
-               /*  becuase we need to free the Tx BCN Desc which is used by the first reserved page packet. */
+               /*  because we need to free the Tx BCN Desc which is used by the first reserved page packet. */
                /*  At run time, we cannot get the Tx Desc until it is released in TxHandleInterrupt() so we will return */
                /*  the beacon TCB in the following code. 2011.11.23. by tynli. */
                /*  */
index 292ba62d722f6235298bb5e54bd2253668b09b5b..52b3fba0fae147590b350f22a93f2690ace4715f 100644 (file)
@@ -19,6 +19,7 @@
  ******************************************************************************/
 #define _HAL_INIT_C_
 
+#include <linux/firmware.h>
 #include <drv_types.h>
 #include <rtw_efuse.h>
 
@@ -588,13 +589,15 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
        u8 writeFW_retry = 0;
        u32 fwdl_start_time;
        struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter);
-
-       u8 *FwImage;
-       u32                     FwImageLen;
+       struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
+       struct device *device = dvobj_to_dev(dvobj);
        struct rt_firmware *pFirmware = NULL;
+       const struct firmware *fw;
        struct rt_firmware_hdr *pFwHdr = NULL;
        u8 *pFirmwareBuf;
-       u32                     FirmwareLen;
+       u32 FirmwareLen;
+       char fw_name[] = "rtlwifi/rtl8188eufw.bin";
+       static int log_version;
 
        RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__));
        pFirmware = (struct rt_firmware *)rtw_zmalloc(sizeof(struct rt_firmware));
@@ -603,27 +606,32 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
                goto Exit;
        }
 
-       FwImage = (u8 *)Rtl8188E_FwImageArray;
-       FwImageLen = Rtl8188E_FWImgArrayLength;
-
-       pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
-
-       switch (pFirmware->eFWSource) {
-       case FW_SOURCE_IMG_FILE:
-               break;
-       case FW_SOURCE_HEADER_FILE:
-               if (FwImageLen > FW_8188E_SIZE) {
-                       rtStatus = _FAIL;
-                       RT_TRACE(_module_hal_init_c_, _drv_err_, ("Firmware size exceed 0x%X. Check it.\n", FW_8188E_SIZE));
-                       goto Exit;
-               }
+       if (request_firmware(&fw, fw_name, device)) {
+               rtStatus = _FAIL;
+               goto Exit;
+       }
+       if (!fw) {
+               pr_err("Firmware %s not available\n", fw_name);
+               rtStatus = _FAIL;
+               goto Exit;
+       }
+       if (fw->size > FW_8188E_SIZE) {
+               rtStatus = _FAIL;
+               RT_TRACE(_module_hal_init_c_, _drv_err_, ("Firmware size exceed 0x%X. Check it.\n", FW_8188E_SIZE));
+               goto Exit;
+       }
 
-               pFirmware->szFwBuffer = FwImage;
-               pFirmware->ulFwLength = FwImageLen;
-               break;
+       pFirmware->szFwBuffer = kzalloc(FW_8188E_SIZE, GFP_KERNEL);
+       if (!pFirmware->szFwBuffer) {
+               rtStatus = _FAIL;
+               goto Exit;
        }
+       memcpy(pFirmware->szFwBuffer, fw->data, fw->size);
+       pFirmware->ulFwLength = fw->size;
        pFirmwareBuf = pFirmware->szFwBuffer;
        FirmwareLen = pFirmware->ulFwLength;
+       release_firmware(fw);
+
        DBG_88E_LEVEL(_drv_info_, "+%s: !bUsedWoWLANFw, FmrmwareLen:%d+\n", __func__, FirmwareLen);
 
        /*  To Check Fw header. Added by tynli. 2009.12.04. */
@@ -633,8 +641,10 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
        pHalData->FirmwareSubVersion = pFwHdr->Subversion;
        pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
 
-       DBG_88E("%s: fw_ver =%d fw_subver =%d sig = 0x%x\n",
-               __func__, pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
+       if (!log_version++)
+               pr_info("%sFirmware Version %d, SubVersion %d, Signature 0x%x\n",
+                       DRIVER_PREFIX, pHalData->FirmwareVersion,
+                       pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
 
        if (IS_FW_HEADER_EXIST(pFwHdr)) {
                /*  Shift 32 bytes for FW header */
@@ -677,7 +687,7 @@ s32 rtl8188e_FirmwareDownload(struct adapter *padapter)
                goto Exit;
        }
        RT_TRACE(_module_hal_init_c_, _drv_info_, ("Firmware is ready to run!\n"));
-
+       kfree(pFirmware->szFwBuffer);
 Exit:
 
        kfree(pFirmware);
@@ -1479,7 +1489,6 @@ static bool hal_EfusePgPacketWrite1ByteHeader(struct adapter *pAdapter, u8 efuse
 
 static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u16 *pAddr, struct pgpkt *pTargetPkt, bool bPseudoTest)
 {
-       bool bRet = false;
        u16     efuse_addr = *pAddr;
        u8 badworden = 0;
        u32     PgWriteSuccess = 0;
@@ -1497,7 +1506,6 @@ static bool hal_EfusePgPacketWriteData(struct adapter *pAdapter, u8 efuseType, u
                else
                        return true;
        }
-       return bRet;
 }
 
 static bool
@@ -1653,7 +1661,7 @@ hal_EfusePgCheckAvailableAddr(
 {
        u16     efuse_max_available_len = 0;
 
-       /* Change to check TYPE_EFUSE_MAP_LEN , beacuse 8188E raw 256, logic map over 256. */
+       /* Change to check TYPE_EFUSE_MAP_LEN , because 8188E raw 256, logic map over 256. */
        EFUSE_GetEfuseDefinition(pAdapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&efuse_max_available_len, false);
 
        if (Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= efuse_max_available_len)
@@ -2100,7 +2108,7 @@ static u8 Hal_GetChnlGroup88E(u8 chnl, u8 *pGroup)
        if (chnl <= 14) {
                bIn24G = true;
 
-               if (chnl < 3)                   /*  Chanel 1-2 */
+               if (chnl < 3)                   /*  Channel 1-2 */
                        *pGroup = 0;
                else if (chnl < 6)              /*  Channel 3-5 */
                        *pGroup = 1;
@@ -2182,7 +2190,7 @@ void Hal_ReadTxPowerInfo88E(struct adapter *padapter, u8 *PROMContent, bool Auto
                pHalData->bTXPowerDataReadFromEEPORM = true;
 
        for (rfPath = 0; rfPath < pHalData->NumTotalRFPath; rfPath++) {
-               for (ch = 0; ch <= CHANNEL_MAX_NUMBER; ch++) {
+               for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) {
                        bIn24G = Hal_GetChnlGroup88E(ch, &group);
                        if (bIn24G) {
                                pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group];
index ff468a68e327b2123125512752991c97e7786d71..68bb96d83c8196f099f15e9832a535c311d7758b 100644 (file)
@@ -559,7 +559,7 @@ static      int phy_BB8188E_Config_ParaFile(struct adapter *Adapter)
 
        /*  */
        /*  1. Read PHY_REG.TXT BB INIT!! */
-       /*  We will seperate as 88C / 92C according to chip version */
+       /*  We will separate as 88C / 92C according to chip version */
        /*  */
        if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG))
                rtStatus = _FAIL;
@@ -685,7 +685,7 @@ static      u8 phy_DbmToTxPwrIdx(struct adapter *Adapter, enum wireless_mode Wireless
 
        /*  */
        /*  Tested by MP, we found that CCK Index 0 equals to 8dbm, OFDM legacy equals to */
-       /*  3dbm, and OFDM HT equals to 0dbm repectively. */
+       /*  3dbm, and OFDM HT equals to 0dbm respectively. */
        /*  Note: */
        /*      The mapping may be different by different NICs. Do not use this formula for what needs accurate result. */
        /*  By Bruce, 2008-01-29. */
@@ -1006,12 +1006,12 @@ _PHY_SetBWMode92C(
        switch (pHalData->CurrentChannelBW) {
        case HT_CHANNEL_WIDTH_20:
                regBwOpMode |= BW_OPMODE_20MHZ;
-               /*  2007/02/07 Mark by Emily becasue we have not verify whether this register works */
+               /*  2007/02/07 Mark by Emily because we have not verify whether this register works */
                rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
                break;
        case HT_CHANNEL_WIDTH_40:
                regBwOpMode &= ~BW_OPMODE_20MHZ;
-               /*  2007/02/07 Mark by Emily becasue we have not verify whether this register works */
+               /*  2007/02/07 Mark by Emily because we have not verify whether this register works */
                rtw_write8(Adapter, REG_BWOPMODE, regBwOpMode);
                regRRSR_RSC = (regRRSR_RSC&0x90) | (pHalData->nCur40MhzPrimeSC<<5);
                rtw_write8(Adapter, REG_RRSR+2, regRRSR_RSC);
index bfdf9b3ce77fefc82ab90bab8930258a59de9a3e..299e03e3daf6bc6e2209c2768232547a2c89d2b5 100644 (file)
@@ -181,7 +181,7 @@ i            *  Currently, we cannot fully disable driver dynamic
                 * tx power mechanism because it is referenced by BT
                 * coexist mechanism.
                 * In the future, two mechanism shall be separated from
-                * each other and maintained independantly. */
+                * each other and maintained independently. */
                if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1) {
                        TxAGC[RF_PATH_A] = 0x10101010;
                        TxAGC[RF_PATH_B] = 0x10101010;
@@ -216,11 +216,11 @@ i          *  Currently, we cannot fully disable driver dynamic
        ODM_TxPwrTrackAdjust88E(&pHalData->odmpriv, 1, &direction, &pwrtrac_value);
 
        if (direction == 1) {
-               /*  Increase TX pwoer */
+               /*  Increase TX power */
                TxAGC[0] += pwrtrac_value;
                TxAGC[1] += pwrtrac_value;
        } else if (direction == 2) {
-               /*  Decrease TX pwoer */
+               /*  Decrease TX power */
                TxAGC[0] -=  pwrtrac_value;
                TxAGC[1] -=  pwrtrac_value;
        }
@@ -292,7 +292,7 @@ static void get_rx_power_val_by_reg(struct adapter *Adapter, u8 Channel,
                        if (pHalData->pwrGroupCnt == 1)
                                chnlGroup = 0;
                        if (pHalData->pwrGroupCnt >= pHalData->PGMaxGroup) {
-                               if (Channel < 3)                        /*  Chanel 1-2 */
+                               if (Channel < 3)                        /*  Channel 1-2 */
                                        chnlGroup = 0;
                                else if (Channel < 6)           /*  Channel 3-5 */
                                        chnlGroup = 1;
@@ -349,7 +349,7 @@ static void get_rx_power_val_by_reg(struct adapter *Adapter, u8 Channel,
                }
 /*  20100427 Joseph: Driver dynamic Tx power shall not affect Tx power. It shall be determined by power training mechanism. */
 /*  Currently, we cannot fully disable driver dynamic tx power mechanism because it is referenced by BT coexist mechanism. */
-/*  In the future, two mechanism shall be separated from each other and maintained independantly. Thanks for Lanhsin's reminder. */
+/*  In the future, two mechanism shall be separated from each other and maintained independently. Thanks for Lanhsin's reminder. */
                /* 92d do not need this */
                if (pdmpriv->DynamicTxHighPowerLvl == TxHighPwrLevel_Level1)
                        writeVal = 0x14141414;
index bd8a9ae5d0770181c2ca0802492224b5f844f6f7..8f43f4966f223d89de22d898c7c716bd7682587f 100644 (file)
@@ -332,7 +332,7 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bag
 
        /*  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 */
+       /*  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. */
index 5e656ce4540702648067333bd4dbc80651e0f419..cca973211b2fe33824eb223674e89074bf62c1eb 100644 (file)
@@ -464,7 +464,7 @@ static void _InitRetryFunction(struct adapter *Adapter)
 /*-----------------------------------------------------------------------------
  * Function:   usb_AggSettingTxUpdate()
  *
- * Overview:   Seperate TX/RX parameters update independent for TP detection and
+ * Overview:   Separate TX/RX parameters update independent for TP detection and
  *                     dynamic TX/RX aggreagtion parameters update.
  *
  * Input:                      struct adapter *
@@ -473,7 +473,7 @@ static void _InitRetryFunction(struct adapter *Adapter)
  *
  * Revised History:
  *     When            Who             Remark
- *     12/10/2010      MHC             Seperate to smaller function.
+ *     12/10/2010      MHC             Separate to smaller function.
  *
  *---------------------------------------------------------------------------*/
 static void usb_AggSettingTxUpdate(struct adapter *Adapter)
@@ -496,7 +496,7 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
 /*-----------------------------------------------------------------------------
  * Function:   usb_AggSettingRxUpdate()
  *
- * Overview:   Seperate TX/RX parameters update independent for TP detection and
+ * Overview:   Separate TX/RX parameters update independent for TP detection and
  *                     dynamic TX/RX aggreagtion parameters update.
  *
  * Input:                      struct adapter *
@@ -505,7 +505,7 @@ static void usb_AggSettingTxUpdate(struct adapter *Adapter)
  *
  * Revised History:
  *     When            Who             Remark
- *     12/10/2010      MHC             Seperate to smaller function.
+ *     12/10/2010      MHC             Separate to smaller function.
  *
  *---------------------------------------------------------------------------*/
 static void
@@ -847,7 +847,7 @@ _func_enter_;
 
        /*  */
        /*  Init CR MACTXEN, MACRXEN after setting RxFF boundary REG_TRXFF_BNDY to patch */
-       /*  Hw bug which Hw initials RxFF boundry size to a value which is larger than the real Rx buffer size in 88E. */
+       /*  Hw bug which Hw initials RxFF boundary size to a value which is larger than the real Rx buffer size in 88E. */
        /*  */
        /*  Enable MACTXEN/MACRXEN block */
        value16 = rtw_read16(Adapter, REG_CR);
index bc564169b2f0560b155a519d2421fc5ae7f71a56..787763ef74c6707d832c34edf0e8ed443cdb3543 100644 (file)
@@ -547,6 +547,8 @@ static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
                RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete : purb->status(%d) != 0\n", purb->status));
 
                DBG_88E("###=> usb_read_port_complete => urb status(%d)\n", purb->status);
+               skb_put(precvbuf->pskb, purb->actual_length);
+               precvbuf->pskb = NULL;
 
                if (rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(adapt)))
                        adapt->bSurpriseRemoved = true;
@@ -605,68 +607,68 @@ _func_enter_;
                return _FAIL;
        }
 
+       if (!precvbuf) {
+               RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
+                        ("usb_read_port:precvbuf==NULL\n"));
+               return _FAIL;
+       }
+
        if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
                precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
                if (NULL != precvbuf->pskb)
                        precvbuf->reuse = true;
        }
 
-       if (precvbuf != NULL) {
-               rtl8188eu_init_recvbuf(adapter, precvbuf);
-
-               /* re-assign for linux based on skb */
-               if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
-                       precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
-                       if (precvbuf->pskb == NULL) {
-                               RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("init_recvbuf(): alloc_skb fail!\n"));
-                               DBG_88E("#### usb_read_port() alloc_skb fail!#####\n");
-                               return _FAIL;
-                       }
-
-                       tmpaddr = (size_t)precvbuf->pskb->data;
-                       alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
-                       skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
-
-                       precvbuf->phead = precvbuf->pskb->head;
-                       precvbuf->pdata = precvbuf->pskb->data;
-                       precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
-                       precvbuf->pend = skb_end_pointer(precvbuf->pskb);
-                       precvbuf->pbuf = precvbuf->pskb->data;
-               } else { /* reuse skb */
-                       precvbuf->phead = precvbuf->pskb->head;
-                       precvbuf->pdata = precvbuf->pskb->data;
-                       precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
-                       precvbuf->pend = skb_end_pointer(precvbuf->pskb);
-                       precvbuf->pbuf = precvbuf->pskb->data;
+       rtl8188eu_init_recvbuf(adapter, precvbuf);
 
-                       precvbuf->reuse = false;
+       /* re-assign for linux based on skb */
+       if ((!precvbuf->reuse) || (precvbuf->pskb == NULL)) {
+               precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
+               if (precvbuf->pskb == NULL) {
+                       RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("init_recvbuf(): alloc_skb fail!\n"));
+                       DBG_88E("#### usb_read_port() alloc_skb fail!#####\n");
+                       return _FAIL;
                }
 
-               precvpriv->rx_pending_cnt++;
+               tmpaddr = (size_t)precvbuf->pskb->data;
+               alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
+               skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
+
+               precvbuf->phead = precvbuf->pskb->head;
+               precvbuf->pdata = precvbuf->pskb->data;
+               precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+               precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+               precvbuf->pbuf = precvbuf->pskb->data;
+       } else { /* reuse skb */
+               precvbuf->phead = precvbuf->pskb->head;
+               precvbuf->pdata = precvbuf->pskb->data;
+               precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
+               precvbuf->pend = skb_end_pointer(precvbuf->pskb);
+               precvbuf->pbuf = precvbuf->pskb->data;
+
+               precvbuf->reuse = false;
+       }
 
-               purb = precvbuf->purb;
+       precvpriv->rx_pending_cnt++;
 
-               /* translate DMA FIFO addr to pipehandle */
-               pipe = ffaddr2pipehdl(pdvobj, addr);
+       purb = precvbuf->purb;
 
-               usb_fill_bulk_urb(purb, pusbd, pipe,
-                                 precvbuf->pbuf,
-                                 MAX_RECVBUF_SZ,
-                                 usb_read_port_complete,
-                                 precvbuf);/* context is precvbuf */
+       /* translate DMA FIFO addr to pipehandle */
+       pipe = ffaddr2pipehdl(pdvobj, addr);
 
-               err = usb_submit_urb(purb, GFP_ATOMIC);
-               if ((err) && (err != (-EPERM))) {
-                       RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
-                                ("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x",
-                                err, purb->status));
-                       DBG_88E("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",
-                               err, purb->status);
-                       ret = _FAIL;
-               }
-       } else {
+       usb_fill_bulk_urb(purb, pusbd, pipe,
+                         precvbuf->pbuf,
+                         MAX_RECVBUF_SZ,
+                         usb_read_port_complete,
+                         precvbuf);/* context is precvbuf */
+
+       err = usb_submit_urb(purb, GFP_ATOMIC);
+       if ((err) && (err != (-EPERM))) {
                RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
-                        ("usb_read_port:precvbuf ==NULL\n"));
+                        ("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x",
+                        err, purb->status));
+               DBG_88E("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",
+                       err, purb->status);
                ret = _FAIL;
        }
 
diff --git a/drivers/staging/rtl8188eu/include/Hal8188EFWImg_CE.h b/drivers/staging/rtl8188eu/include/Hal8188EFWImg_CE.h
deleted file mode 100644 (file)
index 949c33b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/******************************************************************************
-*
-* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
-*
-* This program is free software; you can redistribute it and/or modify it
-* under the terms of version 2 of the GNU General Public License as
-* published by the Free Software Foundation.
-*
-* 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.,
-* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
-*
-*
-******************************************************************************/
-#ifndef __INC_HAL8188E_FW_IMG_H
-#define __INC_HAL8188E_FW_IMG_H
-
-/* V10(1641) */
-#define Rtl8188EFWImgArrayLength 13904
-
-extern const u8 Rtl8188EFwImgArray[Rtl8188EFWImgArrayLength];
-
-#endif /* __INC_HAL8188E_FW_IMG_H */
index c4769e20a5c371149c6c07f8cce71bf6868ced05..25cae8147e732a1519761de9b8bf48379d598b1e 100644 (file)
@@ -75,7 +75,7 @@ enum rf_radio_path {
 
 #define MAX_PG_GROUP 13
 
-#define        RF_PATH_MAX                     2
+#define        RF_PATH_MAX                     3
 #define                MAX_RF_PATH             RF_PATH_MAX
 #define                MAX_TX_COUNT            4 /* path numbers */
 
index 0e06d29b2d2a812622677acb24c41c66ee6bf0b6..9f2969bf8355f1420022174904a3d202e27adf10 100644 (file)
@@ -26,7 +26,7 @@
 /*  2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */
 /*  3. RF register 0x00-2E */
 /*  4. Bit Mask for BB/RF register */
-/*  5. Other defintion for BB/RF R/W */
+/*  5. Other definition for BB/RF R/W */
 /*  */
 
 
index fa583f2483201d587814454ddc79e8e86406b6a9..287e9f9eae4a0b601eac7883149c540236e37963 100644 (file)
@@ -45,8 +45,6 @@ void PHY_IQCalibrate_8188E(struct adapter *Adapter, bool ReCovery);
 void PHY_LCCalibrate_8188E(struct adapter *pAdapter);
 
 /*  AP calibrate */
-void PHY_APCalibrate_8188E(struct adapter *pAdapter, s8 delta);
-
 void PHY_DigitalPredistortion_8188E(struct adapter *pAdapter);
 
 void _PHY_SaveADDARegisters(struct adapter *pAdapter, u32 *ADDAReg,
index 4787bacdcad892da62bf66c05cadb851e090e09d..eaa4bc1b2255b136731e4dcda62e86f196206885 100644 (file)
@@ -283,8 +283,6 @@ struct odm_rate_adapt {
 
 /*  Declare for common info */
 
-#define MAX_PATH_NUM_92CS      2
-
 struct odm_phy_status_info {
        u8      RxPWDBAll;
        u8      SignalQuality;   /*  in 0-100 index. */
@@ -950,7 +948,7 @@ struct odm_dm_struct {
        struct timer_list FastAntTrainingTimer;
 };             /*  DM_Dynamic_Mechanism_Structure */
 
-#define ODM_RF_PATH_MAX 2
+#define ODM_RF_PATH_MAX 3
 
 enum ODM_RF_RADIO_PATH {
        ODM_RF_PATH_A = 0,   /* Radio Path A */
index 63779f5b2a3c142f992593eb1f91ccfb93c4e348..df5272221bad976bbb133b991eddb440749d883c 100644 (file)
@@ -69,7 +69,7 @@ struct phy_rx_agc_info {
 };
 
 struct phy_status_rpt {
-       struct phy_rx_agc_info path_agc[2];
+       struct phy_rx_agc_info path_agc[3];
        u8      ch_corr[2];
        u8      cck_sig_qual_ofdm_pwdb_all;
        u8      cck_agc_rpt_ofdm_cfosho_a;
@@ -79,7 +79,7 @@ struct phy_status_rpt {
        u8      path_cfotail[2];
        u8      pcts_mask[2];
        s8      stream_rxevm[2];
-       u8      path_rxsnr[2];
+       u8      path_rxsnr[3];
        u8      noise_power_db_lsb;
        u8      rsvd_2[3];
        u8      stream_csi[2];
index a9ba6df26b9dc1bbda9211c3e52b389f634af0af..622f4c1418b4759453a73a6c2affbcd03d414b31 100644 (file)
@@ -27,7 +27,7 @@
 /*     Define the debug levels */
 /*  */
 /*     1. DBG_TRACE and DBG_LOUD are used for normal cases. */
-/*     They can help SW engineer to develope or trace states changed */
+/*     They can help SW engineer to develop or trace states changed */
 /*     and also help HW enginner to trace every operation to and from HW, */
 /*     e.g IO, Tx, Rx. */
 /*  */
index 520cbbaac35f8639c3fe8f67e52bcfc3ac8c5870..d1d95f4b87a8208aaf5c3aeaf4eecf32c700f492 100644 (file)
 #include <drv_types.h>
 #include <hal_intf.h>
 
-/* 2 Hardware Parameter Files */
-
-#include "Hal8188EFWImg_CE.h"
-
-
 /* 2 OutSrc Header Files */
 
 #include "odm.h"
index 819285b9a78145eb746660b64d1216cdff82283a..8cafd7adfdcd9dea545c959ce4f40ae67da25f57 100644 (file)
@@ -745,7 +745,7 @@ struct TDLSoption_param
 
 Result:
 0x00: success
-0x01: sucess, and check Response.
+0x01: success, and check Response.
 0x02: cmd ignored due to duplicated sequcne number
 0x03: cmd dropped due to invalid cmd code
 0x04: reserved.
index 2e618043d353ef88459695f59d39f7320b4e36ef..d0da4fd40d18415206876cfe6e179e6a0ef5e5c0 100644 (file)
@@ -163,14 +163,14 @@ enum LED_STRATEGY_871x {
 void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE      LedAction);
 
 struct led_priv{
-       /* add for led controll */
+       /* add for led control */
        struct LED_871x                 SwLed0;
        struct LED_871x                 SwLed1;
        enum LED_STRATEGY_871x  LedStrategy;
        u8      bRegUseLed;
        void (*LedControlHandler)(struct adapter *padapter,
                                  enum LED_CTL_MODE LedAction);
-       /* add for led controll */
+       /* add for led control */
 };
 
 #define rtw_led_control(adapt, action) \
index 22538e61695a12dd0e6ed34dac3e6480f38c13a3..4a7143e0eed0e64f484905b15142654ad3443778 100644 (file)
 #define        WIFI_SITE_MONITOR               0x00000800      /* to indicate the station is under site surveying */
 
 #define        WIFI_MP_STATE                   0x00010000
-#define        WIFI_MP_CTX_BACKGROUND          0x00020000      /*  in continous tx background */
-#define        WIFI_MP_CTX_ST                  0x00040000      /*  in continous tx with single-tone */
-#define        WIFI_MP_CTX_BACKGROUND_PENDING  0x00080000      /*  pending in continous tx background due to out of skb */
-#define        WIFI_MP_CTX_CCK_HW              0x00100000      /*  in continous tx */
-#define        WIFI_MP_CTX_CCK_CS              0x00200000      /*  in continous tx with carrier suppression */
+#define        WIFI_MP_CTX_BACKGROUND          0x00020000      /*  in continuous tx background */
+#define        WIFI_MP_CTX_ST                  0x00040000      /*  in continuous tx with single-tone */
+#define        WIFI_MP_CTX_BACKGROUND_PENDING  0x00080000      /*  pending in continuous tx background due to out of skb */
+#define        WIFI_MP_CTX_CCK_HW              0x00100000      /*  in continuous tx */
+#define        WIFI_MP_CTX_CCK_CS              0x00200000      /*  in continuous tx with carrier suppression */
 #define WIFI_MP_LPBK_STATE             0x00400000
 
 #define _FW_UNDER_LINKING      WIFI_UNDER_LINKING
@@ -239,7 +239,7 @@ struct wifidirect_info {
        u8 profileindex; /* Used to point to the index of profileinfo array */
        u8 peer_operating_ch;
        u8 find_phase_state_exchange_cnt;
-       /* The device password ID for group negotation */
+       /* The device password ID for group negotiation */
        u16 device_password_id_for_nego;
        u8 negotiation_dialog_token;
        /* SSID information for group negotitation */
index 853ab80a2b860a0a95bfab8d85ba064ca4eef982..b1bfa2e30fdbf7c38268a8d8d001940478c30e50 100644 (file)
@@ -107,7 +107,7 @@ extern unsigned char WMM_PARA_OUI[];
 /*  Note: */
 /*     We just add new channel plan when the new channel plan is different
  *      from any of the following channel plan. */
-/*     If you just wnat to customize the acitions(scan period or join actions)
+/*     If you just want to customize the actions(scan period or join actions)
  *      about one of the channel plan, */
 /*     customize them in struct rt_channel_info in the RT_CHANNEL_LIST. */
 enum RT_CHANNEL_DOMAIN {
index 3ad22076de3fc3085bb87d2186b8aa9094496eaf..30fd17f23bf14a326b0138ce8c7b74bae3f8f6df 100644 (file)
@@ -56,7 +56,7 @@
 /*  2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 */
 /*  3. RF register 0x00-2E */
 /*  4. Bit Mask for BB/RF register */
-/*  5. Other defintion for BB/RF R/W */
+/*  5. Other definition for BB/RF R/W */
 /*  */
 
 
index bae8885c57f92c464e9a61b1f14db6b5b70a1b55..be9c30c574198afceab9d01365d743939efdba3a 100644 (file)
@@ -83,7 +83,7 @@ struct signal_stat {
        u32     total_num;              /* num of valid elements */
        u32     total_val;              /* sum of valid elements */
 };
-#define MAX_PATH_NUM_92CS              2
+#define MAX_PATH_NUM_92CS              3
 struct phy_info {
        u8      RxPWDBAll;
        u8      SignalQuality;   /*  in 0-100 index. */
index 089ecee6c1f9e82af842b8552c36a4310f409031..2df88370de59d84a917f9cf59114139b364796f6 100644 (file)
@@ -119,7 +119,7 @@ enum ht_channel_width {
 };
 
 /*  */
-/*  Represent Extention Channel Offset in HT Capabilities */
+/*  Represent Extension Channel Offset in HT Capabilities */
 /*  This is available only in 40Mhz mode. */
 /*  */
 enum ht_extchnl_offset {
index 3ed2a39741adb0c83a61c6a6244847b664e8c6ee..3e909db1d41a84deb8388e10e069aefaac99bfc5 100644 (file)
@@ -338,7 +338,7 @@ struct      sta_priv {
         */
        struct sta_info *sta_aid[NUM_STA];
 
-       u16 sta_dz_bitmap;/* only support 15 stations, staion aid bitmap
+       u16 sta_dz_bitmap;/* only support 15 stations, station aid bitmap
                           * for sleeping sta. */
        u16 tim_bitmap; /* only support 15 stations, aid=0~15 mapping
                         * bit0~bit15 */
index a615659f947171aafee25de62c90116ac27446cb..84e519974199cb3a9c2df3f0742364f185e54f49 100644 (file)
@@ -984,7 +984,7 @@ enum ht_cap_ampdu_factor {
 #define        P2P_PROVISION_TIMEOUT           5000
 /* 3 seconds timeout for sending the prov disc request concurrent mode */
 #define        P2P_CONCURRENT_PROVISION_TIME   3000
-/* 5 seconds timeout for receiving the group negotation response */
+/* 5 seconds timeout for receiving the group negotiation response */
 #define        P2P_GO_NEGO_TIMEOUT             5000
 /* 3 seconds timeout for sending the negotiation request under concurrent mode */
 #define        P2P_CONCURRENT_GO_NEGO_TIME     3000
index 95953ebc027922e66ffd3168a965dee33f6a30be..ae545877023428b103df7af913ca9e10753ed939 100644 (file)
@@ -938,7 +938,7 @@ static int rtw_wx_set_pmkid(struct net_device *dev,
        memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
        if (pPMK->cmd == IW_PMKSA_ADD) {
                DBG_88E("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
-               if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN) == true)
+               if (!memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN))
                        return ret;
                else
                        ret = true;
@@ -1039,7 +1039,7 @@ static int rtw_wx_get_range(struct net_device *dev,
 
        range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
        /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
-       range->avg_qual.level = 20 + -98;
+       range->avg_qual.level = 178; /* -78 dBm */
        range->avg_qual.noise = 0;
        range->avg_qual.updated = 7; /* Updated all three */
 
@@ -1074,7 +1074,7 @@ static int rtw_wx_get_range(struct net_device *dev,
 
 /*  The following code will proivde the security capability to network manager. */
 /*  If the driver doesn't provide this capability to network manager, */
-/*  the WPA/WPA2 routers can't be choosen in the network manager. */
+/*  the WPA/WPA2 routers can't be chosen in the network manager. */
 
 /*
 #define IW_SCAN_CAPA_NONE              0x00
@@ -1373,7 +1373,7 @@ _func_enter_;
                                }
                        }
 
-                       /* it has still some scan paramater to parse, we only do this now... */
+                       /* it has still some scan parameter to parse, we only do this now... */
                        _status = rtw_set_802_11_bssid_list_scan(padapter, ssid, RTW_SSID_SCAN_AMOUNT);
                } else {
                        _status = rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
@@ -2626,7 +2626,7 @@ static int rtw_get_ap_info(struct net_device *dev,
                        return -EINVAL;
                }
 
-               if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == true) {
+               if (!memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN)) {
                        /* BSSID match, then check if supporting wpa/wpa2 */
                        DBG_88E("BSSID:%pM\n", (bssid));
 
@@ -2961,7 +2961,7 @@ static int rtw_p2p_get_status(struct net_device *dev,
 
 /*     Commented by Albert 20110520 */
 /*     This function will return the config method description */
-/*     This config method description will show us which config method the remote P2P device is intented to use */
+/*     This config method description will show us which config method the remote P2P device is intended to use */
 /*     by sending the provisioning discovery request frame. */
 
 static int rtw_p2p_get_req_cm(struct net_device *dev,
@@ -3413,7 +3413,7 @@ static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
        /*  +8 is for the str "InvProc =", we have to clear it at wrqu->data.pointer */
 
        /*      Commented by Ouden 20121226 */
-       /*      The application wants to know P2P initation procedure is support or not. */
+       /*      The application wants to know P2P initiation procedure is supported or not. */
        /*      Format: iwpriv wlanx p2p_get2 InvProc = 00:E0:4C:00:00:05 */
 
        DBG_88E("[%s] data = %s\n", __func__, (char *)extra);
@@ -4040,7 +4040,7 @@ static int rtw_rereg_nd_name(struct net_device *dev,
        if (0 != ret)
                goto exit;
 
-       if (!memcmp(rereg_priv->old_ifname, "disable%d", 9) == true) {
+       if (!memcmp(rereg_priv->old_ifname, "disable%d", 9)) {
                padapter->ledpriv.bRegUseLed = rereg_priv->old_bRegUseLed;
                rtw_hal_sw_led_init(padapter);
                rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode);
@@ -4049,7 +4049,7 @@ static int rtw_rereg_nd_name(struct net_device *dev,
        strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
        rereg_priv->old_ifname[IFNAMSIZ-1] = 0;
 
-       if (!memcmp(new_ifname, "disable%d", 9) == true) {
+       if (!memcmp(new_ifname, "disable%d", 9)) {
                DBG_88E("%s disable\n", __func__);
                /*  free network queue for Android's timming issue */
                rtw_free_network_queue(padapter, true);
@@ -4884,7 +4884,6 @@ static int set_group_key(struct adapter *padapter, u8 *key, u8 alg, int keyid)
        case _TKIP_:
        case _TKIP_WTMIC_:
        case _AES_:
-               keylen = 16;
        default:
                keylen = 16;
        }
@@ -6146,7 +6145,7 @@ static int rtw_mp_efuse_set(struct net_device *dev,
 
                for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
                        setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
-               /* Change to check TYPE_EFUSE_MAP_LEN, beacuse 8188E raw 256, logic map over 256. */
+               /* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */
                EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false);
                if ((addr+cnts) > max_available_size) {
                        DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
@@ -6221,7 +6220,7 @@ static int rtw_mp_efuse_set(struct net_device *dev,
 
                for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
                        setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
-               /* Change to check TYPE_EFUSE_MAP_LEN, beacuse 8188E raw 256, logic map over 256. */
+               /* Change to check TYPE_EFUSE_MAP_LEN, because 8188E raw 256, logic map over 256. */
                EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_size, false);
                if ((addr+cnts) > max_available_size) {
                        DBG_88E("%s: addr(0x%X)+cnts(%d) parameter error!\n", __func__, addr, cnts);
index 63bc913eba6d8a44f83601c8bd385aab6046aba3..da9f0d5f76f758aa05b96d2099c509e896c8b9de 100644 (file)
@@ -85,7 +85,7 @@ static int rtw_uapsd_acvi_en;
 static int rtw_uapsd_acvo_en;
 
 int rtw_ht_enable = 1;
-int rtw_cbw40_enable = 3; /*  0 :diable, bit(0): enable 2.4g, bit(1): enable 5g */
+int rtw_cbw40_enable = 3; /*  0 :disable, bit(0): enable 2.4g, bit(1): enable 5g */
 int rtw_ampdu_enable = 1;/* for enable tx_ampdu */
 static int rtw_rx_stbc = 1;/*  0: disable, bit(0):enable 2.4g, bit(1):enable 5g, default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
 static int rtw_ampdu_amsdu;/*  0: disabled, 1:enabled, 2:auto */
index 4e0bfb7e153b811b75227b9d864b96d49f48676c..5a9e9e4558aa6b60398a00faeb787bafa225e670 100644 (file)
@@ -627,13 +627,14 @@ RETURN:
 int rtw_change_ifname(struct adapter *padapter, const char *ifname)
 {
        struct net_device *pnetdev;
-       struct net_device *cur_pnetdev = padapter->pnetdev;
+       struct net_device *cur_pnetdev;
        struct rereg_nd_name_data *rereg_priv;
        int ret;
 
        if (!padapter)
                goto error;
 
+       cur_pnetdev = padapter->pnetdev;
        rereg_priv = &padapter->rereg_nd_name_priv;
 
        /* free the old_pnetdev */
@@ -794,7 +795,7 @@ void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
 }
 
 /**
- * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization
+ * rtw_cbuf_alloc - allocate a rtw_cbuf with given size and do initialization
  * @size: size of pointer
  *
  * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
index e2f4e7d7717041621acfc29299d81cfe56ee66b5..3852ff43810ddde4944f7f615ba44e503652097f 100644 (file)
@@ -77,8 +77,7 @@ int rtw_os_recvbuf_resource_alloc(struct adapter *padapter,
 int rtw_os_recvbuf_resource_free(struct adapter *padapter,
                                 struct recv_buf *precvbuf)
 {
-       if (precvbuf->purb)
-               usb_free_urb(precvbuf->purb);
+       usb_free_urb(precvbuf->purb);
        return _SUCCESS;
 }
 
@@ -224,8 +223,7 @@ _func_exit_;
 _recv_indicatepkt_drop:
 
         /* enqueue back to free_recv_queue */
-       if (precv_frame)
-               rtw_free_recvframe(precv_frame, pfree_recv_queue);
+       rtw_free_recvframe(precv_frame, pfree_recv_queue);
 
 _func_exit_;
         return _FAIL;
index 9ca3180ebaa0e70fbb188c84748971fd4f34922d..7d14779310d370f7a70b35b56a00ef261bd671af 100644 (file)
@@ -737,7 +737,7 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj,
        status = _SUCCESS;
 
 free_hal_data:
-       if (status != _SUCCESS && padapter->HalData)
+       if (status != _SUCCESS)
                kfree(padapter->HalData);
 handle_dualmac:
        if (status != _SUCCESS)
index f7b14f8b7b8382d4beafb99cc49f28579dae86f4..1260f10944ef07a5c1707f63c74047f8fe9b9687 100644 (file)
@@ -151,7 +151,7 @@ void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr,
                        MaxChnlNum = pTriple->FirstChnl + j;
                }
 
-               pTriple = (struct chnl_txpow_triple *)((u8*)pTriple + 3);
+               pTriple = (struct chnl_txpow_triple *)((u8 *)pTriple + 3);
        }
 
        UPDATE_CIE_SRC(dev, pTaddr);
index 71f4549a378f636019dbac24493adb7b1521c4d0..fb7683fa5ffd93d3bcaee6741e7e6a79bae5828a 100644 (file)
@@ -38,7 +38,7 @@ enum dot11d_state {
 /**
  * struct rt_dot11d_info * @CountryIeLen: value greater than 0 if @CountryIeBuf contains
  *               valid country information element.
- * @chanell_map: holds channel values
+ * @channel_map: holds channel values
  *             0 - invalid,
  *             1 - valid (active scan),
  *             2 - valid (passive scan)
index 74fbd70d583886f3696b8968c77f8b0bdec683ac..6616b3a20bc996611809fa246179b3544d1aaafb 100644 (file)
@@ -1866,15 +1866,15 @@ static void rtl8192_TranslateRxSignalStuff(struct net_device *dev,
        type = WLAN_FC_GET_TYPE(fc);
        praddr = hdr->addr1;
 
-       bpacket_match_bssid = ((RTLLIB_FTYPE_CTL != type) &&
-                       (!compare_ether_addr(priv->rtllib->
-                       current_network.bssid,
-                          (fc & RTLLIB_FCTL_TODS) ? hdr->addr1 :
-                          (fc & RTLLIB_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3))
-               && (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV));
-       bpacket_toself =  bpacket_match_bssid &&        /* check this */
-                         (!compare_ether_addr(praddr,
-                         priv->rtllib->dev->dev_addr));
+       bpacket_match_bssid =
+               ((RTLLIB_FTYPE_CTL != type) &&
+                ether_addr_equal(priv->rtllib->current_network.bssid,
+                                 (fc & RTLLIB_FCTL_TODS) ? hdr->addr1 :
+                                 (fc & RTLLIB_FCTL_FROMDS) ? hdr->addr2 :
+                                 hdr->addr3) &&
+                (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV));
+       bpacket_toself = bpacket_match_bssid &&         /* check this */
+                        ether_addr_equal(praddr, priv->rtllib->dev->dev_addr);
        if (WLAN_FC_GET_FRAMETYPE(fc) == RTLLIB_STYPE_BEACON)
                bPacketBeacon = true;
        if (bpacket_match_bssid)
index e0684435555197a395cebe98e29e5fda9f104bef..b01f6f5c2c44bb6964dbc3b969855069676f0816 100644 (file)
@@ -1888,9 +1888,8 @@ void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
        memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
        skb_push(skb, priv->rtllib->tx_headroom);
        ret = rtl8192_tx(dev, skb);
-       if (ret != 0) {
+       if (ret != 0)
                kfree_skb(skb);
-       };
 
        if (queue_index != MGNT_QUEUE) {
                priv->rtllib->stats.tx_bytes += (skb->len -
@@ -1898,7 +1897,6 @@ void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
                priv->rtllib->stats.tx_packets++;
        }
 
-
        return;
 }
 
@@ -1930,15 +1928,11 @@ int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                tcb_desc->bTxEnableFwCalcDur = 1;
                skb_push(skb, priv->rtllib->tx_headroom);
                ret = rtl8192_tx(dev, skb);
-               if (ret != 0) {
+               if (ret != 0)
                        kfree_skb(skb);
-               };
        }
 
-
-
        return ret;
-
 }
 
 static void rtl8192_tx_isr(struct net_device *dev, int prio)
@@ -2982,7 +2976,6 @@ err_rel_rtllib:
        free_rtllib(dev);
 
        DMESG("wlan driver load failed\n");
-       pci_set_drvdata(pdev, NULL);
 err_pci_disable:
        pci_disable_device(pdev);
        return err;
index 8aeaed5a987d62468022124db2b2deeff92c9afd..8ee80c50303ad8dc07e5b5a3a94cae9e51c19f19 100644 (file)
@@ -957,16 +957,15 @@ static void rtllib_rx_extract_addr(struct rtllib_device *ieee,
 static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc,
                                 u8 *dst, u8 *src, u8 *bssid, u8 *addr2)
 {
-       u8 zero_addr[ETH_ALEN] = {0};
        u8 type, stype;
 
        type = WLAN_FC_GET_TYPE(fc);
        stype = WLAN_FC_GET_STYPE(fc);
 
        /* Filter frames from different BSS */
-       if (((fc & RTLLIB_FCTL_DSTODS) != RTLLIB_FCTL_DSTODS)
-               && (compare_ether_addr(ieee->current_network.bssid, bssid) != 0)
-               && memcmp(ieee->current_network.bssid, zero_addr, ETH_ALEN)) {
+       if (((fc & RTLLIB_FCTL_DSTODS) != RTLLIB_FCTL_DSTODS) &&
+           !ether_addr_equal(ieee->current_network.bssid, bssid) &&
+           !is_zero_ether_addr(ieee->current_network.bssid)) {
                return -1;
        }
 
@@ -974,8 +973,8 @@ static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc,
        if (ieee->IntelPromiscuousModeInfo.bPromiscuousOn  &&
                ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame) {
                if ((fc & RTLLIB_FCTL_TODS) && !(fc & RTLLIB_FCTL_FROMDS) &&
-                       (compare_ether_addr(dst, ieee->current_network.bssid) != 0) &&
-                       (compare_ether_addr(bssid, ieee->current_network.bssid) == 0)) {
+                   !ether_addr_equal(dst, ieee->current_network.bssid) &&
+                   ether_addr_equal(bssid, ieee->current_network.bssid)) {
                        return -1;
                }
        }
@@ -1275,7 +1274,7 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb,
        /*Filter pkt not to me*/
        multicast = is_multicast_ether_addr(hdr->addr1);
        unicast = !multicast;
-       if (unicast && (compare_ether_addr(dev->dev_addr, hdr->addr1) != 0)) {
+       if (unicast && !ether_addr_equal(dev->dev_addr, hdr->addr1)) {
                if (ieee->bNetPromiscuousMode)
                        bToOtherSTA = true;
                else
diff --git a/drivers/staging/rtl8192u/dot11d.h b/drivers/staging/rtl8192u/dot11d.h
deleted file mode 100644 (file)
index 92e7a00..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#include "ieee80211/ieee80211.h"
-
-
-typedef struct _CHNL_TXPOWER_TRIPLE {
-       u8 FirstChnl;
-       u8  NumChnls;
-       u8  MaxTxPowerInDbm;
-} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
-
-typedef enum _DOT11D_STATE {
-       DOT11D_STATE_NONE = 0,
-       DOT11D_STATE_LEARNED,
-       DOT11D_STATE_DONE,
-} DOT11D_STATE;
-
-typedef struct _RT_DOT11D_INFO {
-       /* DECLARE_RT_OBJECT(RT_DOT11D_INFO); */
-
-       bool bEnabled; /* dot11MultiDomainCapabilityEnabled */
-
-       u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */
-       u8  CountryIeBuf[MAX_IE_LEN];
-       u8  CountryIeSrcAddr[6]; /* Source AP of the country IE. */
-       u8  CountryIeWatchdog;
-
-       u8  channel_map[MAX_CHANNEL_NUMBER+1];  /* !Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
-       u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
-
-       DOT11D_STATE State;
-} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a, b)                (((a)[0] == (b)[0] && \
-       (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && \
-       (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0)
-#define cpMacAddr(des, src)          ((des)[0] = (src)[0], \
-       (des)[1] = (src)[1], (des)[2] = (src)[2], \
-       (des)[3] = (src)[3], (des)[4] = (src)[4], \
-       (des)[5] = (src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->bEnabled)
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-
-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
-       (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
-       FALSE : \
-       (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
-
-#define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog)
-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev))
-
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
-
-
-void
-Dot11d_Init(
-       struct ieee80211_device *dev
-       );
-
-void
-Dot11d_Reset(
-       struct ieee80211_device *dev
-       );
-
-void
-Dot11d_UpdateCountryIe(
-       struct ieee80211_device *dev,
-       u8 *pTaddr,
-       u16 CoutryIeLen,
-       u8 *pCoutryIe
-       );
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
-       struct ieee80211_device *dev,
-       u8 Channel
-       );
-
-void
-DOT11D_ScanComplete(
-       struct ieee80211_device *dev
-       );
-
-int IsLegalChannel(
-       struct ieee80211_device *dev,
-       u8 channel
-);
-
-int ToLegalChannel(
-       struct ieee80211_device *dev,
-       u8 channel
-);
-#endif /* #ifndef __INC_DOT11D_H */
index 6aa8c15eba39a09d98e4c963af2dcbfd05dc4b73..bd75e29adc2c41bfccb211e40130c64ae65185a4 100644 (file)
@@ -4,42 +4,43 @@
 #include "ieee80211.h"
 
 
-//#define DOT11D_MAX_CHNL_NUM 83
-
 typedef struct _CHNL_TXPOWER_TRIPLE {
        u8 FirstChnl;
        u8  NumChnls;
        u8  MaxTxPowerInDbm;
-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
+} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
 
 typedef enum _DOT11D_STATE {
        DOT11D_STATE_NONE = 0,
        DOT11D_STATE_LEARNED,
        DOT11D_STATE_DONE,
-}DOT11D_STATE;
+} DOT11D_STATE;
 
 typedef struct _RT_DOT11D_INFO {
-       //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+       /* DECLARE_RT_OBJECT(RT_DOT11D_INFO); */
 
-       bool bEnabled; // dot11MultiDomainCapabilityEnabled
+       bool bEnabled; /* dot11MultiDomainCapabilityEnabled */
 
-       u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
+       u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */
        u8  CountryIeBuf[MAX_IE_LEN];
-       u8  CountryIeSrcAddr[6]; // Source AP of the country IE.
+       u8  CountryIeSrcAddr[6]; /* Source AP of the country IE. */
        u8  CountryIeWatchdog;
 
-       u8  channel_map[MAX_CHANNEL_NUMBER+1];  //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
-       //u8  ChnlListLen; // #Bytes valid in ChnlList[].
-       //u8  ChnlList[DOT11D_MAX_CHNL_NUM];
+       u8  channel_map[MAX_CHANNEL_NUMBER+1];  /* !Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
        u8  MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
 
        DOT11D_STATE State;
-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a,b)         ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
-#define cpMacAddr(des,src)           ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
+} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
+#define eqMacAddr(a, b)                (((a)[0] == (b)[0] && \
+       (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && \
+       (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0)
+#define cpMacAddr(des, src)          ((des)[0] = (src)[0], \
+       (des)[1] = (src)[1], (des)[2] = (src)[2], \
+       (des)[3] = (src)[3], (des)[4] = (src)[4], \
+       (des)[5] = (src)[5])
 #define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
 
-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
+#define IS_DOT11D_ENABLE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->bEnabled)
 #define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
 
 #define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
@@ -51,9 +52,9 @@ typedef struct _RT_DOT11D_INFO {
        (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
 
 #define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
+#define GET_CIE_WATCHDOG(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog)
 #define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
+#define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev))
 
 #define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
 
@@ -72,7 +73,7 @@ void
 Dot11d_UpdateCountryIe(
        struct ieee80211_device *dev,
        u8 *pTaddr,
-       u16     CoutryIeLen,
+       u16 CoutryIeLen,
        u8 *pCoutryIe
        );
 
@@ -96,4 +97,4 @@ int ToLegalChannel(
        struct ieee80211_device *dev,
        u8 channel
 );
-#endif // #ifndef __INC_DOT11D_H
+#endif /* #ifndef __INC_DOT11D_H */
index 434c431271834f9e28a36e19108392c5ffaa65ae..4b036a8db5a18ca14bc66ad8215e412f1ef68dd0 100644 (file)
@@ -241,7 +241,7 @@ static int debug = \
                            //IEEE80211_DL_DATA |
                            IEEE80211_DL_ERR      //awayls open this flags to show error out
                            ;
-struct proc_dir_entry *ieee80211_proc;
+static struct proc_dir_entry *ieee80211_proc;
 
 static int show_debug_level(struct seq_file *m, void *v)
 {
index 59900bfa1c18f250edbbefb732c5828760e888e3..e730ed64c0fe3775d4567cdd01036d72d0bb8fdf 100644 (file)
@@ -2166,7 +2166,8 @@ static inline u8 ieee80211_SignalStrengthTranslate(
        return RetSS;
 }
 
-long ieee80211_translate_todbm(u8 signal_strength_index        )// 0-100 index.
+/* 0-100 index */
+static long ieee80211_translate_todbm(u8 signal_strength_index)
 {
        long    signal_power; // in dBm.
 
index a7bcc64ff2263684717ce87c39980522a37854a9..157b2d7466e5f606f107442ab44ca0c9647d4a1d 100644 (file)
@@ -237,8 +237,8 @@ void ieee80211_txb_free(struct ieee80211_txb *txb) {
        kfree(txb);
 }
 
-struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
-                                         int gfp_mask)
+static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
+                                                gfp_t gfp_mask)
 {
        struct ieee80211_txb *txb;
        int i;
@@ -303,7 +303,8 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
 }
 
 #define SN_LESS(a, b)          (((a-b)&0x800)!=0)
-void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee, struct sk_buff *skb, cb_desc *tcb_desc)
+static void ieee80211_tx_query_agg_cap(struct ieee80211_device *ieee,
+                                      struct sk_buff *skb, cb_desc *tcb_desc)
 {
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
        PTX_TS_RECORD                   pTxTs = NULL;
@@ -412,7 +413,8 @@ ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
                tcb_desc->bUseShortGI = true;
 }
 
-void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee, cb_desc *tcb_desc)
+static void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee,
+                                         cb_desc *tcb_desc)
 {
        PRT_HIGH_THROUGHPUT     pHTInfo = ieee->pHTInfo;
 
@@ -432,7 +434,9 @@ void ieee80211_query_BandwidthMode(struct ieee80211_device *ieee, cb_desc *tcb_d
        return;
 }
 
-void ieee80211_query_protectionmode(struct ieee80211_device *ieee, cb_desc *tcb_desc, struct sk_buff *skb)
+static void ieee80211_query_protectionmode(struct ieee80211_device *ieee,
+                                          cb_desc *tcb_desc,
+                                          struct sk_buff *skb)
 {
        // Common Settings
        tcb_desc->bRTSSTBC                      = false;
@@ -543,7 +547,8 @@ NO_PROTECTION:
 }
 
 
-void ieee80211_txrate_selectmode(struct ieee80211_device *ieee, cb_desc *tcb_desc)
+static void ieee80211_txrate_selectmode(struct ieee80211_device *ieee,
+                                       cb_desc *tcb_desc)
 {
 #ifdef TO_DO_LIST
        if(!IsDataFrame(pFrame))
@@ -573,7 +578,8 @@ void ieee80211_txrate_selectmode(struct ieee80211_device *ieee, cb_desc *tcb_des
        }
 }
 
-void ieee80211_query_seqnum(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *dst)
+static void ieee80211_query_seqnum(struct ieee80211_device *ieee,
+                                  struct sk_buff *skb, u8 *dst)
 {
        if (is_multicast_ether_addr(dst))
                return;
index db0db9347487db1b1ca16e26f46d2bf305eaf728..3684da340bd48d32633fcb1d7a6dd14b4155390f 100644 (file)
@@ -251,7 +251,8 @@ static struct sk_buff *ieee80211_DELBA(
  *  output:  none
  *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
 ********************************************************************************************************************/
-void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee, u8 *dst, PBA_RECORD        pBA)
+static void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee,
+                                   u8 *dst, PBA_RECORD pBA)
 {
        struct sk_buff *skb = NULL;
        skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero.
@@ -278,7 +279,8 @@ void ieee80211_send_ADDBAReq(struct ieee80211_device *ieee, u8 *dst, PBA_RECORD
  *  output:  none
  *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
 ********************************************************************************************************************/
-void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst, PBA_RECORD pBA, u16 StatusCode)
+static void ieee80211_send_ADDBARsp(struct ieee80211_device *ieee, u8 *dst,
+                                   PBA_RECORD pBA, u16 StatusCode)
 {
        struct sk_buff *skb = NULL;
        skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames
diff --git a/drivers/staging/rtl8192u/ieee80211_crypt.h b/drivers/staging/rtl8192u/ieee80211_crypt.h
deleted file mode 100644 (file)
index 0b4ea43..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Original code based on Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- *
- * Copyright (c) 2004, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-/*
- * This file defines the interface to the ieee80211 crypto module.
- */
-#ifndef IEEE80211_CRYPT_H
-#define IEEE80211_CRYPT_H
-
-#include <linux/skbuff.h>
-
-struct ieee80211_crypto_ops {
-       const char *name;
-
-       /* init new crypto context (e.g., allocate private data space,
-        * select IV, etc.); returns NULL on failure or pointer to allocated
-        * private data on success */
-       void * (*init)(int keyidx);
-
-       /* deinitialize crypto context and free allocated private data */
-       void (*deinit)(void *priv);
-
-       /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
-        * value from decrypt_mpdu is passed as the keyidx value for
-        * decrypt_msdu. skb must have enough head and tail room for the
-        * encryption; if not, error will be returned; these functions are
-        * called for all MPDUs (i.e., fragments).
-        */
-       int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-       int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-
-       /* These functions are called for full MSDUs, i.e. full frames.
-        * These can be NULL if full MSDU operations are not needed. */
-       int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
-       int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
-                           void *priv);
-
-       int (*set_key)(void *key, int len, u8 *seq, void *priv);
-       int (*get_key)(void *key, int len, u8 *seq, void *priv);
-
-       /* procfs handler for printing out key information and possible
-        * statistics */
-       char * (*print_stats)(char *p, void *priv);
-
-       /* maximum number of bytes added by encryption; encrypt buf is
-        * allocated with extra_prefix_len bytes, copy of in_buf, and
-        * extra_postfix_len; encrypt need not use all this space, but
-        * the result must start at the beginning of the buffer and correct
-        * length must be returned */
-       int extra_prefix_len, extra_postfix_len;
-
-       struct module *owner;
-};
-
-struct ieee80211_crypt_data {
-       struct list_head list; /* delayed deletion list */
-       struct ieee80211_crypto_ops *ops;
-       void *priv;
-       atomic_t refcnt;
-};
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
-void ieee80211_crypt_deinit_handler(unsigned long);
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
-                                   struct ieee80211_crypt_data **crypt);
-
-#endif
diff --git a/drivers/staging/rtl8192u/r8180_pm.c b/drivers/staging/rtl8192u/r8180_pm.c
deleted file mode 100644 (file)
index 999968d..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-   Power management interface routines.
-   Written by Mariusz Matuszek.
-   This code is currently just a placeholder for later work and
-   does not do anything useful.
-
-   This is part of rtl8180 OpenSource driver.
-   Copyright (C) Andrea Merello 2004  <andrea.merello@gmail.com>
-   Released under the terms of GPL (General Public Licence)
-*/
-
-#ifdef CONFIG_RTL8180_PM
-
-
-#include "r8180_hw.h"
-#include "r8180_pm.h"
-
-int rtl8180_save_state (struct pci_dev *dev, u32 state)
-{
-       printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
-       return(-EAGAIN);
-}
-
-
-int rtl8180_suspend (struct pci_dev *dev, u32 state)
-{
-       printk(KERN_NOTICE "r8180 suspend call (state %u).\n", state);
-       return(-EAGAIN);
-}
-
-
-int rtl8180_resume (struct pci_dev *dev)
-{
-       printk(KERN_NOTICE "r8180 resume call.\n");
-       return(-EAGAIN);
-}
-
-
-int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
-{
-       printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
-              state, enable);
-       return(-EAGAIN);
-}
-
-
-
-#endif //CONFIG_RTL8180_PM
diff --git a/drivers/staging/rtl8192u/r8180_pm.h b/drivers/staging/rtl8192u/r8180_pm.h
deleted file mode 100644 (file)
index 4be63da..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-       Power management interface routines.
-       Written by Mariusz Matuszek.
-       This code is currently just a placeholder for later work and
-       does not do anything useful.
-
-       This is part of rtl8180 OpenSource driver.
-       Copyright (C) Andrea Merello 2004  <andrea.merello@gmail.com>
-       Released under the terms of GPL (General Public Licence)
-
-*/
-
-#ifdef CONFIG_RTL8180_PM
-
-#ifndef R8180_PM_H
-#define R8180_PM_H
-
-#include <linux/types.h>
-#include <linux/pci.h>
-
-int rtl8180_save_state (struct pci_dev *dev, u32 state);
-int rtl8180_suspend (struct pci_dev *dev, u32 state);
-int rtl8180_resume (struct pci_dev *dev);
-int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
-
-#endif //R8180_PM_H
-
-#endif // CONFIG_RTL8180_PM
index 592e7807fa4288edc63cbd14076c62e663df161d..fa6dd37d85e6680d76aaa5909f9f9040d7930d7a 100644 (file)
 #ifndef RTL8225H
 #define RTL8225H
 
-#ifdef RTL8190P
-#define RTL819X_TOTAL_RF_PATH 4 //for 90P
-#else
 #define RTL819X_TOTAL_RF_PATH 2 //for 8192U
-#endif
 extern void PHY_SetRF8256Bandwidth(struct net_device *dev , HT_CHANNEL_WIDTH Bandwidth);
 extern void PHY_RF8256_Config(struct net_device *dev);
 extern void phy_RF8256_Config_ParaFile(struct net_device *dev);
index b484ee128c13fd1227f686a2bee544c8a54f192a..ad3bc567d35a18ac0dbe2cd0026085b37db67f05 100644 (file)
@@ -409,15 +409,11 @@ typedef struct rx_drvinfo_819x_usb {
 #define        USB_HWDESC_HEADER_LEN           sizeof(tx_desc_819x_usb)
 #define TX_PACKET_SHIFT_BYTES          (USB_HWDESC_HEADER_LEN + sizeof(tx_fwinfo_819x_usb))
 #define MAX_FRAGMENT_COUNT             8
-#ifdef RTL8192U
 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
 #define MAX_TRANSMIT_BUFFER_SIZE                       32000
 #else
 #define MAX_TRANSMIT_BUFFER_SIZE                       8000
 #endif
-#else
-#define MAX_TRANSMIT_BUFFER_SIZE       (1600+(MAX_802_11_HEADER_LENGTH+ENCRYPTION_MAX_OVERHEAD)*MAX_FRAGMENT_COUNT)
-#endif
 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
 #define TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES (sizeof(tx_desc_819x_usb_aggr_subframe) + sizeof(tx_fwinfo_819x_usb))
 #endif
@@ -1158,14 +1154,6 @@ typedef enum {
        NIC_8192E = 3,
 } nic_t;
 
-
-#ifdef JOHN_HWSEC
-struct ssid_thread {
-       struct net_device *dev;
-       u8 name[IW_ESSID_MAX_SIZE + 1];
-};
-#endif
-
 bool init_firmware(struct net_device *dev);
 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
 short rtl8192_tx(struct net_device *dev, struct sk_buff *skb);
index cd0946db025c3c51fd7d98ae46f88f0675606b5c..63a4cdf1dc048c601a8adeed251a7eca1b8ac801 100644 (file)
@@ -392,7 +392,7 @@ int read_nic_word(struct net_device *dev, int indx, u16 *data)
        return 0;
 }
 
-int read_nic_word_E(struct net_device *dev, int indx, u16 *data)
+static int read_nic_word_E(struct net_device *dev, int indx, u16 *data)
 {
        int status;
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
@@ -585,7 +585,7 @@ static int proc_get_stats_rx(struct seq_file *m, void *v)
        return 0;
 }
 
-void rtl8192_proc_module_init(void)
+static void rtl8192_proc_module_init(void)
 {
        RT_TRACE(COMP_INIT, "Initializing proc filesystem");
        rtl8192_proc = proc_mkdir(RTL819xU_MODULE_NAME, init_net.proc_net);
@@ -631,7 +631,7 @@ static const struct rtl8192_proc_file rtl8192_proc_files[] = {
        { "" }
 };
 
-void rtl8192_proc_init_one(struct net_device *dev)
+static void rtl8192_proc_init_one(struct net_device *dev)
 {
        const struct rtl8192_proc_file *f;
        struct proc_dir_entry *dir;
@@ -656,7 +656,7 @@ void rtl8192_proc_init_one(struct net_device *dev)
        }
 }
 
-void rtl8192_proc_remove_one(struct net_device *dev)
+static void rtl8192_proc_remove_one(struct net_device *dev)
 {
        remove_proc_subtree(dev->name, rtl8192_proc);
 }
@@ -755,7 +755,7 @@ void rtl8192_set_chan(struct net_device *dev, short ch)
 
 static void rtl8192_rx_isr(struct urb *urb);
 
-u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
+static u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
 {
 
 #ifdef USB_RX_AGGREGATION_SUPPORT
@@ -998,8 +998,8 @@ static void rtl8192_rx_isr(struct urb *urb)
                netdev_err(dev, "can not submit rxurb, err is %x, URB status is %x\n", err, urb->status);
 }
 
-u32 rtl819xusb_rx_command_packet(struct net_device *dev,
-                                struct ieee80211_rx_stats *pstats)
+static u32 rtl819xusb_rx_command_packet(struct net_device *dev,
+                                       struct ieee80211_rx_stats *pstats)
 {
        u32     status;
 
@@ -1608,13 +1608,6 @@ short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
        idx_pipe = txqueue2outpipe(priv, queue_index);
 #else
        idx_pipe = 0x04;
-#endif
-#ifdef JOHN_DUMP_TXDESC
-       int i;
-       printk("<Tx descriptor>--rate %x---", rate);
-       for (i = 0; i < 8; i++)
-               printk("%8x ", tx[i]);
-       printk("\n");
 #endif
        usb_fill_bulk_urb(tx_urb, priv->udev, usb_sndbulkpipe(priv->udev, idx_pipe),
                          skb->data, skb->len, rtl8192_tx_isr, skb);
@@ -1636,7 +1629,7 @@ short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
  *
  * \param QUEUEID       Software Queue
 */
-u8 MapHwQueueToFirmwareQueue(u8 QueueID)
+static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
 {
        u8 QueueSelect = 0x0;       //defualt set to
 
@@ -1723,7 +1716,7 @@ u8 MRateToHwRate8190Pci(u8 rate)
 }
 
 
-u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
+static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
 {
        u8   tmp_Short;
 
@@ -1934,7 +1927,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb)
        }
 }
 
-short rtl8192_usb_initendpoints(struct net_device *dev)
+static short rtl8192_usb_initendpoints(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
 
@@ -1992,7 +1985,7 @@ short rtl8192_usb_initendpoints(struct net_device *dev)
 
 }
 #ifdef THOMAS_BEACON
-void rtl8192_usb_deleteendpoints(struct net_device *dev)
+static void rtl8192_usb_deleteendpoints(struct net_device *dev)
 {
        int i;
        struct r8192_priv *priv = ieee80211_priv(dev);
@@ -2009,7 +2002,7 @@ void rtl8192_usb_deleteendpoints(struct net_device *dev)
        priv->oldaddr = NULL;
        if (priv->pp_rxskb) {
                kfree(priv->pp_rxskb);
-               priv->pp_rxskb = 0;
+               priv->pp_rxskb = NULL;
        }
 }
 #else
@@ -2292,7 +2285,7 @@ void rtl8192_update_ratr_table(struct net_device *dev)
 
 static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04};
 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
-bool GetNmodeSupportBySecCfg8192(struct net_device *dev)
+static bool GetNmodeSupportBySecCfg8192(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        struct ieee80211_device *ieee = priv->ieee80211;
@@ -3167,7 +3160,7 @@ static struct net_device_stats *rtl8192_stats(struct net_device *dev)
        return &priv->ieee80211->stats;
 }
 
-bool HalTxCheckStuck819xUsb(struct net_device *dev)
+static bool HalTxCheckStuck819xUsb(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        u16             RegTxCounter;
@@ -3217,7 +3210,7 @@ RESET_TYPE TxCheckStuck(struct net_device *dev)
        return RESET_TYPE_NORESET;
 }
 
-bool HalRxCheckStuck819xUsb(struct net_device *dev)
+static bool HalRxCheckStuck819xUsb(struct net_device *dev)
 {
        u16     RegRxCounter;
        struct r8192_priv *priv = ieee80211_priv(dev);
@@ -3259,7 +3252,7 @@ bool HalRxCheckStuck819xUsb(struct net_device *dev)
        return bStuck;
 }
 
-RESET_TYPE RxCheckStuck(struct net_device *dev)
+static RESET_TYPE RxCheckStuck(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
        bool        bRxCheck = FALSE;
@@ -3859,15 +3852,6 @@ int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                                }
                        }
                }
-#ifdef JOHN_HWSEC_DEBUG
-               //john's test 0711
-               printk("@@ wrq->u pointer = ");
-               for (i = 0; i < wrq->u.data.length; i++) {
-                       if (i%10 == 0) printk("\n");
-                       printk("%8x|", ((u32 *)wrq->u.data.pointer)[i]);
-               }
-               printk("\n");
-#endif /*JOHN_HWSEC_DEBUG*/
                ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
                break;
 
@@ -3952,7 +3936,8 @@ u8 HwRateToMRate90(bool bIsHT, u8 rate)
  * Return:
  *               None
  */
-void UpdateRxPktTimeStamp8190(struct net_device *dev, struct ieee80211_rx_stats *stats)
+static void UpdateRxPktTimeStamp8190(struct net_device *dev,
+                                    struct ieee80211_rx_stats *stats)
 {
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 
@@ -4209,7 +4194,7 @@ static u8 rtl819x_evm_dbtopercentage(char value)
 //     We want good-looking for signal strength/quality
 //     2007/7/19 01:09, by cosa.
 //
-long rtl819x_signal_scale_mapping(long currsig)
+static long rtl819x_signal_scale_mapping(long currsig)
 {
        long retsig;
 
@@ -4478,9 +4463,9 @@ void rtl8192_record_rxdesc_forlateruse(struct ieee80211_rx_stats *psrc_stats,
 }
 
 
-void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
-                                  struct ieee80211_rx_stats *pstats,
-                                  rx_drvinfo_819x_usb  *pdrvinfo)
+static void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
+                                         struct ieee80211_rx_stats *pstats,
+                                         rx_drvinfo_819x_usb  *pdrvinfo)
 {
        // TODO: We must only check packet for current MAC address. Not finish
        rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
@@ -4549,8 +4534,9 @@ void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
 * Return:
 *              None
 */
-void UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
-                                              struct ieee80211_rx_stats *stats)
+static void
+UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
+                                         struct ieee80211_rx_stats *stats)
 {
        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
        u32 rcvType = 1;   //0: Total, 1:OK, 2:CRC, 3:ICV
@@ -4614,7 +4600,9 @@ void UpdateReceivedRateHistogramStatistics8190(struct net_device *dev,
 }
 
 
-void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
+static void query_rxdesc_status(struct sk_buff *skb,
+                               struct ieee80211_rx_stats *stats,
+                               bool bIsRxAggrSubframe)
 {
        rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
        struct net_device *dev = info->dev;
@@ -4930,7 +4918,8 @@ void rtl819xusb_process_received_packet(struct net_device *dev,
 
 }
 
-void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
+static void query_rx_cmdpkt_desc_status(struct sk_buff *skb,
+                                       struct ieee80211_rx_stats *stats)
 {
        rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
 
index a6e4c37d9c78e2d2fc305e1fd0e7862ca9d07c78..41fb67b7337d876985d9e25dcc50f73949f8cf8f 100644 (file)
@@ -100,14 +100,6 @@ static     void    dm_check_txpower_tracking(struct net_device *dev);
 //static       void    dm_txpower_reset_recovery(struct net_device *dev);
 
 
-// DM --> BB init gain restore
-#ifndef RTL8192U
-static void    dm_bb_initialgain_restore(struct net_device *dev);
-
-
-// DM --> BB init gain backup
-static void    dm_bb_initialgain_backup(struct net_device *dev);
-#endif
 // DM --> Dynamic Init Gain by RSSI
 static void    dm_dig_init(struct net_device *dev);
 static void    dm_ctrl_initgain_byrssi(struct net_device *dev);
@@ -122,12 +114,7 @@ static     void dm_init_ctstoself(struct net_device *dev);
 // DM --> EDCA turbo mode control
 static void    dm_check_edca_turbo(struct net_device *dev);
 
-// DM --> HW RF control
-static void    dm_check_rfctrl_gpio(struct net_device *dev);
-
-#ifndef RTL8190P
 //static       void    dm_gpio_change_rf(struct net_device *dev);
-#endif
 // DM --> Check PBC
 static void dm_check_pbc_gpio(struct net_device *dev);
 
@@ -269,7 +256,6 @@ extern  void    hal_dm_watchdog(struct net_device *dev)
        dm_ctrl_initgain_byrssi(dev);
        dm_check_edca_turbo(dev);
        dm_bandwidth_autoswitch(dev);
-       dm_check_rfctrl_gpio(dev);
        dm_check_rx_path_selection(dev);
        dm_check_fsync(dev);
 
@@ -620,16 +606,11 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
        tx_cmd.Op               = TXCMD_SET_TX_PWR_TRACKING;
        tx_cmd.Length   = 4;
        tx_cmd.Value            = Value;
-#ifdef RTL8192U
        rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
        if (rtStatus == RT_STATUS_FAILURE)
        {
                RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
        }
-#else
-       cmpk_message_handle_tx(dev, (u8 *)&tx_cmd,
-                                                               DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
-#endif
        mdelay(1);
        //DbgPrint("hi, vivi, strange\n");
        for(i = 0;i <= 30; i++)
@@ -641,11 +622,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                        mdelay(1);
                        continue;
                }
-#ifdef RTL8190P
-               read_nic_word(dev, 0x1bc, &Avg_TSSI_Meas);
-#else
                read_nic_word(dev, 0x13c, &Avg_TSSI_Meas);
-#endif
                if(Avg_TSSI_Meas == 0)
                {
                        write_nic_byte(dev, 0x1ba, 0);
@@ -654,14 +631,10 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
 
                for(k = 0;k < 5; k++)
                {
-#ifdef RTL8190P
-                       read_nic_byte(dev, 0x1d8+k, &tmp_report[k]);
-#else
                        if(k !=4)
                                read_nic_byte(dev, 0x134+k, &tmp_report[k]);
                        else
                                read_nic_byte(dev, 0x13e, &tmp_report[k]);
-#endif
                        RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
                }
 
@@ -708,10 +681,6 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                        RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
                        RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
                        RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
-#ifdef RTL8190P
-                       RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
-                       RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
-#endif
                        RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
                        RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
                        return;
@@ -720,11 +689,7 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                {
                        if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
                        {
-                               if((priv->rfa_txpowertrackingindex > 0)
-#ifdef RTL8190P
-                                       &&(priv->rfc_txpowertrackingindex > 0)
-#endif
-                               )
+                               if (priv->rfa_txpowertrackingindex > 0)
                                {
                                        priv->rfa_txpowertrackingindex--;
                                        if(priv->rfa_txpowertrackingindex_real > 4)
@@ -732,33 +697,16 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                                                priv->rfa_txpowertrackingindex_real--;
                                                rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
                                        }
-#ifdef RTL8190P
-                                       priv->rfc_txpowertrackingindex--;
-                                       if(priv->rfc_txpowertrackingindex_real > 4)
-                                       {
-                                               priv->rfc_txpowertrackingindex_real--;
-                                               rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
-                                       }
-#endif
                                }
                        }
                        else
                        {
-                               if((priv->rfa_txpowertrackingindex < 36)
-#ifdef RTL8190P
-                                       &&(priv->rfc_txpowertrackingindex < 36)
-#endif
-                                       )
+                               if (priv->rfa_txpowertrackingindex < 36)
                                {
                                        priv->rfa_txpowertrackingindex++;
                                        priv->rfa_txpowertrackingindex_real++;
                                        rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
 
-#ifdef RTL8190P
-                                       priv->rfc_txpowertrackingindex++;
-                                       priv->rfc_txpowertrackingindex_real++;
-                                       rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
-#endif
                                }
                        }
                        priv->cck_present_attentuation_difference
@@ -788,10 +736,6 @@ static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
                        }
                RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
                RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
-#ifdef RTL8190P
-               RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
-               RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
-#endif
                RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
                RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
 
@@ -937,14 +881,10 @@ extern    void    dm_txpower_trackingcallback(struct work_struct *work)
        struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
        struct net_device *dev = priv->ieee80211->dev;
 
-#ifdef RTL8190P
-       dm_TXPowerTrackingCallback_TSSI(dev);
-#else
        if(priv->bDcut == TRUE)
                dm_TXPowerTrackingCallback_TSSI(dev);
        else
                dm_TXPowerTrackingCallback_ThermalMeter(dev);
-#endif
 }
 
 
@@ -1472,14 +1412,10 @@ static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
 void dm_initialize_txpower_tracking(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
-#ifdef RTL8190P
-       dm_InitializeTXPowerTracking_TSSI(dev);
-#else
        if(priv->bDcut == TRUE)
                dm_InitializeTXPowerTracking_TSSI(dev);
        else
                dm_InitializeTXPowerTracking_ThermalMeter(dev);
-#endif
 }// dm_InitializeTXPowerTracking
 
 
@@ -1677,14 +1613,10 @@ extern void dm_cck_txpower_adjust(
 {      // dm_CCKTxPowerAdjust
 
        struct r8192_priv *priv = ieee80211_priv(dev);
-#ifdef RTL8190P
-       dm_CCKTxPowerAdjust_TSSI(dev, binch14);
-#else
        if(priv->bDcut == TRUE)
                dm_CCKTxPowerAdjust_TSSI(dev, binch14);
        else
                dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
-#endif
 }
 
 
@@ -2194,11 +2126,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
                {
                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
-                       #else
-                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
-                       #endif
+                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
                        */
@@ -2265,11 +2193,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
                {
                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
-                       #else
-                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
-                       #endif
+                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
                        /*
                        else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
@@ -2342,11 +2266,7 @@ static void dm_ctrl_initgain_byrssi_highpwr(
                // 3.1 Higher PD_TH for OFDM for high power state.
                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
                {
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
-                       #else
-                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
-                       #endif
+                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
 
                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
@@ -2370,11 +2290,7 @@ static void dm_ctrl_initgain_byrssi_highpwr(
                        // 3.2 Recover PD_TH for OFDM for normal power region.
                        if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
                        {
-                               #ifdef RTL8190P
-                                       write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
-                               #else
-                                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
-                               #endif
+                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
                                /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                        write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
                                */
@@ -2516,11 +2432,7 @@ static void dm_pd_th(
                                {
                                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
                                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
-                                       #ifdef RTL8190P
-                                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
-                                       #else
-                                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
-                                       #endif
+                                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
                                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
                                        */
@@ -2535,11 +2447,7 @@ static void dm_pd_th(
                                {
                                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
                                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
-                                       #ifdef RTL8190P
-                                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
-                                       #else
-                                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
-                                       #endif
+                                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
                                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
                                        */
@@ -2552,11 +2460,7 @@ static void dm_pd_th(
                                // Higher PD_TH for OFDM for high power state.
                                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
                                {
-                                       #ifdef RTL8190P
-                                               write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
-                                       #else
-                                               write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
-                                       #endif
+                                       write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
                                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
                                        */
@@ -2823,44 +2727,6 @@ static void dm_ctstoself(struct net_device *dev)
        }
 }
 
-
-/*-----------------------------------------------------------------------------
- * Function:   dm_check_rfctrl_gpio()
- *
- * Overview:   Copy 8187B template for 9xseries.
- *
- * Input:              NONE
- *
- * Output:             NONE
- *
- * Return:             NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     05/28/2008      amy             Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-static void dm_check_rfctrl_gpio(struct net_device *dev)
-{
-       //struct r8192_priv *priv = ieee80211_priv(dev);
-
-       // Work around for DTM test, we will not enable HW - radio on/off because r/w
-       // page 1 register before extra bus is enabled causing system failures when resuming
-       // from S4. 20080218, Emily
-
-       // Stop to execute workitem to prevent S3/S4 bug.
-#ifdef RTL8190P
-       return;
-#endif
-#ifdef RTL8192U
-       return;
-#endif
-#ifdef RTL8192E
-               queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
-#endif
-
-}      /* dm_CheckRfCtrlGPIO */
-
 /*-----------------------------------------------------------------------------
  * Function:   dm_check_pbc_gpio()
  *
@@ -2879,7 +2745,6 @@ static void dm_check_rfctrl_gpio(struct net_device *dev)
  *---------------------------------------------------------------------------*/
 static void    dm_check_pbc_gpio(struct net_device *dev)
 {
-#ifdef RTL8192U
        struct r8192_priv *priv = ieee80211_priv(dev);
        u8 tmp1byte;
 
@@ -2895,83 +2760,9 @@ static   void    dm_check_pbc_gpio(struct net_device *dev)
                RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
                priv->bpbc_pressed = true;
        }
-#endif
 
 }
 
-#ifdef RTL8192E
-
-/*-----------------------------------------------------------------------------
- * Function:   dm_GPIOChangeRF
- * Overview:   PCI will not support workitem call back HW radio on-off control.
- *
- * Input:              NONE
- *
- * Output:             NONE
- *
- * Return:             NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     02/21/2008      MHC             Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-extern void    dm_gpio_change_rf_callback(struct work_struct *work)
-{
-       struct delayed_work *dwork = container_of(work,struct delayed_work,work);
-       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
-       struct net_device *dev = priv->ieee80211->dev;
-       u8 tmp1byte;
-       RT_RF_POWER_STATE       eRfPowerStateToSet;
-       bool bActuallySet = false;
-
-       do{
-               bActuallySet=false;
-
-               if(!priv->up)
-               {
-                       RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
-               }
-               else
-               {
-                       // 0x108 GPIO input register is read only
-                       //set 0x108 B1= 1: RF-ON; 0: RF-OFF.
-                       read_nic_byte(dev, GPI, &tmp1byte);
-
-                       eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
-
-                       if((priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
-                       {
-                               RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
-
-                               priv->bHwRadioOff = false;
-                               bActuallySet = true;
-                       }
-                       else if ((priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
-                       {
-                               RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
-                               priv->bHwRadioOff = true;
-                               bActuallySet = true;
-                       }
-
-                       if(bActuallySet)
-                       {
-                               #ifdef TO_DO
-                               MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
-                               //DrvIFIndicateCurrentPhyStatus(pAdapter);
-                               #endif
-                       }
-                       else
-                       {
-                               msleep(2000);
-                       }
-
-               }
-       }while(TRUE)
-
-}      /* dm_GPIOChangeRF */
-
-#endif
 /*-----------------------------------------------------------------------------
  * Function:   DM_RFPathCheckWorkItemCallBack()
  *
@@ -3329,11 +3120,7 @@ static void dm_init_fsync (struct net_device *dev)
        priv->ieee80211->fsync_time_interval = 500;
        priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
        priv->ieee80211->fsync_rssi_threshold = 30;
-#ifdef RTL8190P
-       priv->ieee80211->bfsync_enable = true;
-#else
        priv->ieee80211->bfsync_enable = false;
-#endif
        priv->ieee80211->fsync_multiple_timeinterval = 3;
        priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
        priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
@@ -3416,20 +3203,12 @@ extern void dm_fsync_timer_callback(unsigned long data)
                        priv->bswitch_fsync = !priv->bswitch_fsync;
                        if(priv->bswitch_fsync)
                        {
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, 0xC36, 0x00);
-                       #else
                                write_nic_byte(dev,0xC36, 0x1c);
-                       #endif
                                write_nic_byte(dev, 0xC3e, 0x90);
                        }
                        else
                        {
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, 0xC36, 0x40);
-                       #else
                                write_nic_byte(dev, 0xC36, 0x5c);
-                       #endif
                                write_nic_byte(dev, 0xC3e, 0x96);
                        }
                }
@@ -3438,11 +3217,7 @@ extern void dm_fsync_timer_callback(unsigned long data)
                        if(priv->bswitch_fsync)
                        {
                                priv->bswitch_fsync  = false;
-                       #ifdef RTL8190P
-                               write_nic_byte(dev, 0xC36, 0x40);
-                       #else
                                write_nic_byte(dev, 0xC36, 0x5c);
-                       #endif
                                write_nic_byte(dev, 0xC3e, 0x96);
                        }
                }
@@ -3465,19 +3240,11 @@ extern void dm_fsync_timer_callback(unsigned long data)
                if(priv->bswitch_fsync)
                {
                        priv->bswitch_fsync  = false;
-               #ifdef RTL8190P
-                       write_nic_byte(dev, 0xC36, 0x40);
-               #else
                        write_nic_byte(dev, 0xC36, 0x5c);
-               #endif
                        write_nic_byte(dev, 0xC3e, 0x96);
                }
                priv->ContinueDiffCount = 0;
-       #ifdef RTL8190P
-               write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd);
-       #else
                write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
-       #endif
        }
        RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
        RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
@@ -3502,19 +3269,13 @@ static void dm_EndSWFsync(struct net_device *dev)
        {
                priv->bswitch_fsync  = false;
 
-               #ifdef RTL8190P
-                       write_nic_byte(dev, 0xC36, 0x40);
-               #else
-                       write_nic_byte(dev, 0xC36, 0x5c);
-               #endif
+               write_nic_byte(dev, 0xC36, 0x5c);
 
                write_nic_byte(dev, 0xC3e, 0x96);
        }
 
        priv->ContinueDiffCount = 0;
-#ifndef RTL8190P
        write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
-#endif
 
 }
 
@@ -3553,9 +3314,7 @@ static void dm_StartSWFsync(struct net_device *dev)
        priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
        add_timer(&priv->fsync_timer);
 
-#ifndef RTL8190P
        write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
-#endif
 
 }
 
@@ -3624,11 +3383,7 @@ void dm_check_fsync(struct net_device *dev)
                {
                        if(reg_c38_State != RegC38_Fsync_AP_BCM)
                        {       //For broadcom AP we write different default value
-                               #ifdef RTL8190P
-                                       write_nic_byte(dev, rOFDM0_RxDetector3, 0x15);
-                               #else
-                                       write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
-                               #endif
+                               write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
 
                                reg_c38_State = RegC38_Fsync_AP_BCM;
                        }
@@ -3659,11 +3414,7 @@ void dm_check_fsync(struct net_device *dev)
                                {
                                        if(reg_c38_State != RegC38_NonFsync_Other_AP)
                                        {
-                                               #ifdef RTL8190P
-                                                       write_nic_byte(dev, rOFDM0_RxDetector3, 0x10);
-                                               #else
-                                                       write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
-                                               #endif
+                                               write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
 
                                                reg_c38_State = RegC38_NonFsync_Other_AP;
                                        }
@@ -3845,10 +3596,8 @@ static void dm_dynamic_txpower(struct net_device *dev)
                SetTxPowerLevel8190(Adapter,pHalData->CurrentChannel);
 #endif
 
-#ifdef RTL8192U
                rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
                //pHalData->bStartTxCtrlByTPCNFR = FALSE;    //Clear th flag of Set TX Power from Sitesurvey
-#endif
        }
        priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
        priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
@@ -3885,9 +3634,6 @@ static void dm_send_rssi_tofw(struct net_device *dev)
        tx_cmd.Op               = TXCMD_SET_RX_RSSI;
        tx_cmd.Length   = 4;
        tx_cmd.Value            = priv->undecorated_smoothed_pwdb;
-
-       cmpk_message_handle_tx(dev, (u8 *)&tx_cmd,
-                                                               DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
 }
 
 /*---------------------------Define function prototype------------------------*/
index 61f6620213e2e99881f76835eb51ea3bc6709b15..c70af014a31670428b67205763be1f2a786f42a0 100644 (file)
@@ -127,156 +127,6 @@ static int r8192_wx_get_power(struct net_device *dev,
        return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
 }
 
-#ifdef JOHN_IOCTL
-u16 read_rtl8225(struct net_device *dev, u8 addr);
-void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
-u32 john_read_rtl8225(struct net_device *dev, u8 adr);
-void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
-
-static int r8192_wx_read_regs(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u8 addr;
-       u16 data1;
-
-       down(&priv->wx_sem);
-
-
-       get_user(addr,(u8 *)wrqu->data.pointer);
-       data1 = read_rtl8225(dev, addr);
-       wrqu->data.length = data1;
-
-       up(&priv->wx_sem);
-       return 0;
-
-}
-
-static int r8192_wx_write_regs(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u8 addr;
-
-       down(&priv->wx_sem);
-
-       get_user(addr, (u8 *)wrqu->data.pointer);
-       write_rtl8225(dev, addr, wrqu->data.length);
-
-       up(&priv->wx_sem);
-       return 0;
-
-}
-
-void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
-u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
-
-static int r8192_wx_read_bb(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u8 databb;
-
-       down(&priv->wx_sem);
-
-       databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
-       wrqu->data.length = databb;
-
-       up(&priv->wx_sem);
-       return 0;
-}
-
-void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
-static int r8192_wx_write_bb(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u8 databb;
-
-       down(&priv->wx_sem);
-
-       get_user(databb, (u8 *)wrqu->data.pointer);
-       rtl8187_write_phy(dev, wrqu->data.length, databb);
-
-       up(&priv->wx_sem);
-       return 0;
-
-}
-
-
-static int r8192_wx_write_nicb(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u32 addr;
-
-       down(&priv->wx_sem);
-
-       get_user(addr, (u32 *)wrqu->data.pointer);
-       write_nic_byte(dev, addr, wrqu->data.length);
-
-       up(&priv->wx_sem);
-       return 0;
-
-}
-static int r8192_wx_read_nicb(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       u32 addr;
-       u16 data1;
-
-       down(&priv->wx_sem);
-
-       get_user(addr,(u32 *)wrqu->data.pointer);
-       read_nic_byte(dev, addr, &data1);
-       wrqu->data.length = data1;
-
-       up(&priv->wx_sem);
-       return 0;
-}
-
-static int r8192_wx_get_ap_status(struct net_device *dev,
-                              struct iw_request_info *info,
-                              union iwreq_data *wrqu, char *extra)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
-       struct ieee80211_device *ieee = priv->ieee80211;
-       struct ieee80211_network *target;
-       int name_len;
-
-       down(&priv->wx_sem);
-
-       //count the length of input ssid
-       for(name_len=0 ; ((char *)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
-
-       //search for the corresponding info which is received
-       list_for_each_entry(target, &ieee->network_list, list) {
-               if ( (target->ssid_len == name_len) &&
-                    (strncmp(target->ssid, (char *)wrqu->data.pointer, name_len)==0)){
-                       if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
-                               //set flags=1 to indicate this ap is WPA
-                               wrqu->data.flags = 1;
-                       else wrqu->data.flags = 0;
-
-
-               break;
-               }
-       }
-
-       up(&priv->wx_sem);
-       return 0;
-}
-
-
-
-#endif
 static int r8192_wx_force_reset(struct net_device *dev,
                struct iw_request_info *info,
                union iwreq_data *wrqu, char *extra)
@@ -1106,46 +956,7 @@ static const struct iw_priv_args r8192_private_args[] = {
        {
                SIOCIWFIRSTPRIV + 0x2,
                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
-       }
-#ifdef JOHN_IOCTL
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x3,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x4,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x5,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x6,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x7,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x8,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
-       }
-       ,
-       {
-               SIOCIWFIRSTPRIV + 0x9,
-               IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
-       }
-
-#endif
-       ,
+       },
        {
                SIOCIWFIRSTPRIV + 0x3,
                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
@@ -1163,15 +974,6 @@ static iw_handler r8192_private_handler[] = {
 //     r8192_wx_set_monitor_type,
        r8192_wx_set_scan_type,
        r8192_wx_set_rawtx,
-#ifdef JOHN_IOCTL
-       r8192_wx_read_regs,
-       r8192_wx_write_regs,
-       r8192_wx_read_bb,
-       r8192_wx_write_bb,
-       r8192_wx_read_nicb,
-       r8192_wx_write_nicb,
-       r8192_wx_get_ap_status,
-#endif
        //r8192_wx_null,
        r8192_wx_force_reset,
 };
index 19a7bdd1973ad3bdc02c61657cb891362141dbec..2cbb8e6584f893fb6ab714a8ad57dd4ef356e7cb 100644 (file)
@@ -2,41 +2,36 @@
 #define _R819XU_HTTYPE_H_
 
 
-//------------------------------------------------------------
-// The HT Capability element is present in beacons, association request,
-//     reassociation request and probe response frames
-//------------------------------------------------------------
-
-//
-// Operation mode value
-//
+/*----------------------------------------------------------------------
+ * The HT Capability element is present in beacons, association request,
+ * reassociation request and probe response frames
+ *----------------------------------------------------------------------*/
+
+/* Operation mode value */
 #define HT_OPMODE_NO_PROTECT           0
 #define HT_OPMODE_OPTIONAL             1
-#define HT_OPMODE_40MHZ_PROTECT        2
+#define HT_OPMODE_40MHZ_PROTECT                2
 #define HT_OPMODE_MIXED                        3
 
-//
-// MIMO Power Save Settings
-//
-#define MIMO_PS_STATIC                         0
+/* MIMO Power Save Settings */
+#define MIMO_PS_STATIC                 0
 #define MIMO_PS_DYNAMIC                        1
 #define MIMO_PS_NOLIMIT                        3
 
 
-//
-//     There should be 128 bits to cover all of the MCS rates. However, since
-//     8190 does not support too much rates, one integer is quite enough.
-//
+/* There should be 128 bits to cover all of the MCS rates. However, since
+ * 8190 does not support too much rates, one integer is quite enough. */
 
-#define sHTCLng        4
+#define sHTCLng                                4
 
 
-#define HT_SUPPORTED_MCS_1SS_BITMAP                                    0x000000ff
-#define HT_SUPPORTED_MCS_2SS_BITMAP                                    0x0000ff00
-#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP                        HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
+#define HT_SUPPORTED_MCS_1SS_BITMAP    0x000000ff
+#define HT_SUPPORTED_MCS_2SS_BITMAP    0x0000ff00
+#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP        \
+               (HT_MCS_1SS_BITMAP | HT_MCS_1SS_2SS_BITMAP)
 
 
-typedef enum _HT_MCS_RATE{
+typedef enum _HT_MCS_RATE {
        HT_MCS0   = 0x00000001,
        HT_MCS1   = 0x00000002,
        HT_MCS2   = 0x00000004,
@@ -47,71 +42,67 @@ typedef enum _HT_MCS_RATE{
        HT_MCS7   = 0x00000080,
        HT_MCS8   = 0x00000100,
        HT_MCS9   = 0x00000200,
-       HT_MCS10 = 0x00000400,
-       HT_MCS11 = 0x00000800,
-       HT_MCS12 = 0x00001000,
-       HT_MCS13 = 0x00002000,
-       HT_MCS14 = 0x00004000,
-       HT_MCS15 = 0x00008000,
-       // Do not define MCS32 here although 8190 support MCS32
-}HT_MCS_RATE,*PHT_MCS_RATE;
-
-//
-// Represent Channel Width in HT Capabilities
-//
-typedef enum _HT_CHANNEL_WIDTH{
-       HT_CHANNEL_WIDTH_20 = 0,
+       HT_MCS10  = 0x00000400,
+       HT_MCS11  = 0x00000800,
+       HT_MCS12  = 0x00001000,
+       HT_MCS13  = 0x00002000,
+       HT_MCS14  = 0x00004000,
+       HT_MCS15  = 0x00008000,
+       /* Do not define MCS32 here although 8190 support MCS32 */
+} HT_MCS_RATE, *PHT_MCS_RATE;
+
+/* Represent Channel Width in HT Capabilities */
+typedef enum _HT_CHANNEL_WIDTH {
+       HT_CHANNEL_WIDTH_20    = 0,
        HT_CHANNEL_WIDTH_20_40 = 1,
-}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
+} HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
 
-//
-// Represent Extension Channel Offset in HT Capabilities
-// This is available only in 40Mhz mode.
-//
-typedef enum _HT_EXTCHNL_OFFSET{
+/* Represent Extension Channel Offset in HT Capabilities
+ * This is available only in 40Mhz mode. */
+typedef enum _HT_EXTCHNL_OFFSET {
        HT_EXTCHNL_OFFSET_NO_EXT = 0,
-       HT_EXTCHNL_OFFSET_UPPER = 1,
+       HT_EXTCHNL_OFFSET_UPPER  = 1,
        HT_EXTCHNL_OFFSET_NO_DEF = 2,
-       HT_EXTCHNL_OFFSET_LOWER = 3,
-}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
-
-typedef enum _CHNLOP{
-       CHNLOP_NONE = 0, // No Action now
-       CHNLOP_SCAN = 1, // Scan in progress
-       CHNLOP_SWBW = 2, // Bandwidth switching in progress
-       CHNLOP_SWCHNL = 3, // Software Channel switching in progress
+       HT_EXTCHNL_OFFSET_LOWER  = 3,
+} HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
+
+typedef enum _CHNLOP {
+       CHNLOP_NONE   = 0,      /* No Action now */
+       CHNLOP_SCAN   = 1,      /* Scan in progress */
+       CHNLOP_SWBW   = 2,      /* Bandwidth switching in progress */
+       CHNLOP_SWCHNL = 3,      /* Software Channel switching in progress */
 } CHNLOP, *PCHNLOP;
 
-// Determine if the Channel Operation is in progress
+/* Determine if the Channel Operation is in progress */
 #define CHHLOP_IN_PROGRESS(_pHTInfo)   \
-               ((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
+               (((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE)
 
 
-typedef enum _HT_ACTION{
+typedef enum _HT_ACTION {
        ACT_RECOMMAND_WIDTH             = 0,
        ACT_MIMO_PWR_SAVE               = 1,
-       ACT_PSMP                                        = 2,
+       ACT_PSMP                        = 2,
        ACT_SET_PCO_PHASE               = 3,
-       ACT_MIMO_CHL_MEASURE    = 4,
-       ACT_RECIPROCITY_CORRECT = 5,
+       ACT_MIMO_CHL_MEASURE            = 4,
+       ACT_RECIPROCITY_CORRECT         = 5,
        ACT_MIMO_CSI_MATRICS            = 6,
-       ACT_MIMO_NOCOMPR_STEER  = 7,
+       ACT_MIMO_NOCOMPR_STEER          = 7,
        ACT_MIMO_COMPR_STEER            = 8,
        ACT_ANTENNA_SELECT              = 9,
 } HT_ACTION, *PHT_ACTION;
 
 
-/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */
-typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{
+/* Define sub-carrier mode for 40MHZ. */
+typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier {
        SC_MODE_DUPLICATE = 0,
-       SC_MODE_LOWER = 1,
-       SC_MODE_UPPER = 2,
+       SC_MODE_LOWER     = 1,
+       SC_MODE_UPPER     = 2,
        SC_MODE_FULL40MHZ = 3,
-}HT_BW40_SC_E;
+} HT_BW40_SC_E;
 
-typedef        struct _HT_CAPABILITY_ELE{
+typedef        struct _HT_CAPABILITY_ELE {
 
-       //HT capability info
+       /* HT capability info */
        u8      AdvCoding:1;
        u8      ChlWidth:1;
        u8      MimoPwrSave:2;
@@ -127,32 +118,32 @@ typedef   struct _HT_CAPABILITY_ELE{
        u8      Rsvd1:1;
        u8      LSigTxopProtect:1;
 
-       //MAC HT parameters info
+       /* MAC HT parameters info */
        u8      MaxRxAMPDUFactor:2;
        u8      MPDUDensity:3;
        u8      Rsvd2:3;
 
-       //Supported MCS set
+       /* Supported MCS set */
        u8      MCS[16];
 
 
-       //Extended HT Capability Info
+       /* Extended HT Capability Info */
        u16     ExtHTCapInfo;
 
-       //TXBF Capabilities
+       /* TXBF Capabilities */
        u8      TxBFCap[4];
 
-       //Antenna Selection Capabilities
+       /* Antenna Selection Capabilities */
        u8      ASCap;
 
-}__attribute__((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
+} __packed HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
 
-//------------------------------------------------------------
-// The HT Information element is present in beacons
-// Only AP is required to include this element
-//------------------------------------------------------------
+/*------------------------------------------------------------
+ * The HT Information element is present in beacons
+ * Only AP is required to include this element
+ *------------------------------------------------------------*/
 
-typedef struct _HT_INFORMATION_ELE{
+typedef struct _HT_INFORMATION_ELE {
        u8      ControlChl;
 
        u8      ExtChlOffset:2;
@@ -177,146 +168,146 @@ typedef struct _HT_INFORMATION_ELE{
        u8      Rsvd4:4;
 
        u8      BasicMSC[16];
-}__attribute__((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
+} __packed HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
 
-//
-// MIMO Power Save control field.
-// This is appear in MIMO Power Save Action Frame
-//
-typedef struct _MIMOPS_CTRL{
+/* MIMO Power Save control field.
+ * This is appear in MIMO Power Save Action Frame */
+typedef struct _MIMOPS_CTRL {
        u8      MimoPsEnable:1;
        u8      MimoPsMode:1;
        u8      Reserved:6;
 } MIMOPS_CTRL, *PMIMOPS_CTRL;
 
-typedef enum _HT_SPEC_VER{
+typedef enum _HT_SPEC_VER {
        HT_SPEC_VER_IEEE = 0,
        HT_SPEC_VER_EWC = 1,
-}HT_SPEC_VER, *PHT_SPEC_VER;
+} HT_SPEC_VER, *PHT_SPEC_VER;
 
-typedef enum _HT_AGGRE_MODE_E{
+typedef enum _HT_AGGRE_MODE_E {
        HT_AGG_AUTO = 0,
        HT_AGG_FORCE_ENABLE = 1,
        HT_AGG_FORCE_DISABLE = 2,
-}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
-
-//------------------------------------------------------------
-//  The Data structure is used to keep HT related variables when card is
-//  configured as non-AP STA mode.  **Note**  Current_xxx should be set
-//     to default value in HTInitializeHTInfo()
-//------------------------------------------------------------
-
-typedef struct _RT_HIGH_THROUGHPUT{
-//     DECLARE_RT_OBJECT(_RT_HIGH_THROUGHPUT);
-       u8                              bEnableHT;
-       u8                              bCurrentHTSupport;
-
-       u8                              bRegBW40MHz;                            // Tx 40MHz channel capability
-       u8                              bCurBW40MHz;                            // Tx 40MHz channel capability
-
-       u8                              bRegShortGI40MHz;                       // Tx Short GI for 40Mhz
-       u8                              bCurShortGI40MHz;                       // Tx Short GI for 40MHz
-
-       u8                              bRegShortGI20MHz;                       // Tx Short GI for 20MHz
-       u8                              bCurShortGI20MHz;                       // Tx Short GI for 20MHz
-
-       u8                              bRegSuppCCK;                            // Tx CCK rate capability
-       u8                              bCurSuppCCK;                            // Tx CCK rate capability
-
-       // 802.11n spec version for "peer"
-       HT_SPEC_VER                     ePeerHTSpecVer;
-
+} HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
 
-       // HT related information for "Self"
-       HT_CAPABILITY_ELE       SelfHTCap;                                      // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
-       HT_INFORMATION_ELE      SelfHTInfo;                                     // This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
+/*----------------------------------------------------------------------------
+ *  The Data structure is used to keep HT related variables when card is
+ *  configured as non-AP STA mode.
+ *  **Note** Current_xxx should be set to default value in HTInitializeHTInfo()
+ *----------------------------------------------------------------------------*/
 
-       // HT related information for "Peer"
-       u8                              PeerHTCapBuf[32];
-       u8                              PeerHTInfoBuf[32];
-
-
-       // A-MSDU related
-       u8                              bAMSDU_Support;                 // This indicates Tx A-MSDU capability
-       u16                             nAMSDU_MaxSize;                 // This indicates Tx A-MSDU capability
-       u8                              bCurrent_AMSDU_Support; // This indicates Tx A-MSDU capability
-       u16                             nCurrent_AMSDU_MaxSize; // This indicates Tx A-MSDU capability
-
-
-       // AMPDU  related <2006.08.10 Emily>
-       u8                              bAMPDUEnable;                           // This indicate Tx A-MPDU capability
-       u8                              bCurrentAMPDUEnable;            // This indicate Tx A-MPDU capability
-       u8                              AMPDU_Factor;                           // This indicate Tx A-MPDU capability
-       u8                              CurrentAMPDUFactor;             // This indicate Tx A-MPDU capability
-       u8                              MPDU_Density;                           // This indicate Tx A-MPDU capability
-       u8                              CurrentMPDUDensity;                     // This indicate Tx A-MPDU capability
+typedef struct _RT_HIGH_THROUGHPUT {
+       u8                      bEnableHT;
+       u8                      bCurrentHTSupport;
+       /* Tx 40MHz channel capability */
+       u8                      bRegBW40MHz;
+       u8                      bCurBW40MHz;
+       /* Tx Short GI for 40Mhz */
+       u8                      bRegShortGI40MHz;
+       u8                      bCurShortGI40MHz;
+       /* Tx Short GI for 20MHz */
+       u8                      bRegShortGI20MHz;
+       u8                      bCurShortGI20MHz;
+       /* Tx CCK rate capability */
+       u8                      bRegSuppCCK;
+       u8                      bCurSuppCCK;
+
+       /* 802.11n spec version for "peer" */
+       HT_SPEC_VER             ePeerHTSpecVer;
+
+
+       /* HT related information for "Self" */
+       /* This is HT cap element sent to peer STA, which also indicate
+        * HT Rx capabilities. */
+       HT_CAPABILITY_ELE       SelfHTCap;
+       HT_INFORMATION_ELE      SelfHTInfo;
+
+       /* HT related information for "Peer" */
+       u8                      PeerHTCapBuf[32];
+       u8                      PeerHTInfoBuf[32];
+
+
+       /* A-MSDU related */
+       /* This indicates Tx A-MSDU capability */
+       u8                      bAMSDU_Support;
+       u16                     nAMSDU_MaxSize;
+       u8                      bCurrent_AMSDU_Support;
+       u16                     nCurrent_AMSDU_MaxSize;
+
+
+       /* A-MPDU related */
+       /* This indicate Tx A-MPDU capability */
+       u8                      bAMPDUEnable;
+       u8                      bCurrentAMPDUEnable;
+       u8                      AMPDU_Factor;
+       u8                      CurrentAMPDUFactor;
+       u8                      MPDU_Density;
+       u8                      CurrentMPDUDensity;
 
-       // Forced A-MPDU enable
-       HT_AGGRE_MODE_E ForcedAMPDUMode;
-       u8                              ForcedAMPDUFactor;
-       u8                              ForcedMPDUDensity;
+       /* Forced A-MPDU enable */
+       HT_AGGRE_MODE_E         ForcedAMPDUMode;
+       u8                      ForcedAMPDUFactor;
+       u8                      ForcedMPDUDensity;
 
-       // Forced A-MSDU enable
-       HT_AGGRE_MODE_E ForcedAMSDUMode;
-       u16                             ForcedAMSDUMaxSize;
+       /* Forced A-MSDU enable */
+       HT_AGGRE_MODE_E         ForcedAMSDUMode;
+       u16                     ForcedAMSDUMaxSize;
 
-       u8                              bForcedShortGI;
+       u8                      bForcedShortGI;
 
-       u8                              CurrentOpMode;
+       u8                      CurrentOpMode;
 
-       // MIMO PS related
-       u8                              SelfMimoPs;
-       u8                              PeerMimoPs;
+       /* MIMO PS related */
+       u8                      SelfMimoPs;
+       u8                      PeerMimoPs;
 
-       // 40MHz Channel Offset settings.
+       /* 40MHz Channel Offset settings. */
        HT_EXTCHNL_OFFSET       CurSTAExtChnlOffset;
-       u8                              bCurTxBW40MHz;  // If we use 40 MHz to Tx
-       u8                              PeerBandwidth;
-
-       // For Bandwidth Switching
-       u8                              bSwBwInProgress;
-       CHNLOP                          ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
-       u8                              SwBwStep;
-       //RT_TIMER                      SwBwTimer;
-       struct timer_list               SwBwTimer;
-
-       // For Realtek proprietary A-MPDU factor for aggregation
-       u8                              bRegRT2RTAggregation;
-       u8                              bCurrentRT2RTAggregation;
-       u8                              bCurrentRT2RTLongSlotTime;
-       u8                              szRT2RTAggBuffer[10];
-
-       // Rx Reorder control
-       u8                              bRegRxReorderEnable;
-       u8                              bCurRxReorderEnable;
-       u8                              RxReorderWinSize;
-       u8                              RxReorderPendingTime;
-       u16                             RxReorderDropCounter;
+       u8                      bCurTxBW40MHz;  /* If we use 40 MHz to Tx */
+       u8                      PeerBandwidth;
+
+       /* For Bandwidth Switching */
+       u8                      bSwBwInProgress;
+       CHNLOP                  ChnlOp; /* sw switching channel in progress. */
+       u8                      SwBwStep;
+       struct timer_list       SwBwTimer;
+
+       /* For Realtek proprietary A-MPDU factor for aggregation */
+       u8                      bRegRT2RTAggregation;
+       u8                      bCurrentRT2RTAggregation;
+       u8                      bCurrentRT2RTLongSlotTime;
+       u8                      szRT2RTAggBuffer[10];
+
+       /* Rx Reorder control */
+       u8                      bRegRxReorderEnable;
+       u8                      bCurRxReorderEnable;
+       u8                      RxReorderWinSize;
+       u8                      RxReorderPendingTime;
+       u16                     RxReorderDropCounter;
 
 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-       u8                              UsbTxAggrNum;
+       u8                      UsbTxAggrNum;
 #endif
 #ifdef USB_RX_AGGREGATION_SUPPORT
-       u8                              UsbRxFwAggrEn;
-       u8                              UsbRxFwAggrPageNum;
-       u8                              UsbRxFwAggrPacketNum;
-       u8                              UsbRxFwAggrTimeout;
+       u8                      UsbRxFwAggrEn;
+       u8                      UsbRxFwAggrPageNum;
+       u8                      UsbRxFwAggrPacketNum;
+       u8                      UsbRxFwAggrTimeout;
 #endif
 
-       // Add for Broadcom(Linksys) IOT. Joseph
-       u8                              bIsPeerBcm;
+       /* Add for Broadcom(Linksys) IOT. */
+       u8                      bIsPeerBcm;
 
-       // For IOT issue.
-       u32                                     IOTAction;
-}RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
+       /* For IOT issue. */
+       u32                     IOTAction;
+} RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
 
 
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variable for "each Sta"
-// when card is configured as "AP mode"
-//------------------------------------------------------------
+/*----------------------------------------------------------------------
+ * The Data structure is used to keep HT related variable for "each Sta"
+ * when card is configured as "AP mode"
+ *----------------------------------------------------------------------*/
 
-typedef struct _RT_HTINFO_STA_ENTRY{
+typedef struct _RT_HTINFO_STA_ENTRY {
        u8                      bEnableHT;
 
        u8                      bSupportCck;
@@ -335,56 +326,54 @@ typedef struct _RT_HTINFO_STA_ENTRY{
        u8                      McsRateSet[16];
 
 
-}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
+} RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
 
 
 
 
 
-//------------------------------------------------------------
-// The Data structure is used to keep HT related variable for "each AP"
-// when card is configured as "STA mode"
-//------------------------------------------------------------
+/*---------------------------------------------------------------------
+ * The Data structure is used to keep HT related variable for "each AP"
+ * when card is configured as "STA mode"
+ *---------------------------------------------------------------------*/
 
-typedef struct _BSS_HT{
+typedef struct _BSS_HT {
 
        u8                              bdSupportHT;
 
-       // HT related elements
-       u8                                      bdHTCapBuf[32];
-       u16                                     bdHTCapLen;
-       u8                                      bdHTInfoBuf[32];
-       u16                                     bdHTInfoLen;
+       /* HT related elements */
+       u8                              bdHTCapBuf[32];
+       u16                             bdHTCapLen;
+       u8                              bdHTInfoBuf[32];
+       u16                             bdHTInfoLen;
 
-       HT_SPEC_VER                             bdHTSpecVer;
-       //HT_CAPABILITY_ELE                     bdHTCapEle;
-       //HT_INFORMATION_ELE            bdHTInfoEle;
+       HT_SPEC_VER                     bdHTSpecVer;
 
-       u8                                      bdRT2RTAggregation;
-       u8                                      bdRT2RTLongSlotTime;
-}BSS_HT, *PBSS_HT;
+       u8                              bdRT2RTAggregation;
+       u8                              bdRT2RTLongSlotTime;
+} BSS_HT, *PBSS_HT;
 
-typedef struct _MIMO_RSSI{
+typedef struct _MIMO_RSSI {
        u32     EnableAntenna;
        u32     AntennaA;
        u32     AntennaB;
        u32     AntennaC;
        u32     AntennaD;
        u32     Average;
-}MIMO_RSSI, *PMIMO_RSSI;
+} MIMO_RSSI, *PMIMO_RSSI;
 
-typedef struct _MIMO_EVM{
+typedef struct _MIMO_EVM {
        u32     EVM1;
-       u32    EVM2;
-}MIMO_EVM, *PMIMO_EVM;
+       u32     EVM2;
+} MIMO_EVM, *PMIMO_EVM;
 
-typedef struct _FALSE_ALARM_STATISTICS{
+typedef struct _FALSE_ALARM_STATISTICS {
        u32     Cnt_Parity_Fail;
-       u32    Cnt_Rate_Illegal;
+       u32     Cnt_Rate_Illegal;
        u32     Cnt_Crc8_fail;
        u32     Cnt_all;
-}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
+} FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
 
 
 
-#endif //__INC_HTTYPE_H
+#endif
index 56144014b7c9ba15126f97b073fb6eea4777937a..7bdcbd39a3b25a3fb8c4d7eaaf6e95ac59b64ad9 100644 (file)
@@ -61,105 +61,6 @@ rt_status SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen)
        return rtStatus;
 }
 
-/*-----------------------------------------------------------------------------
- * Function:   cmpk_message_handle_tx()
- *
- * Overview:   Driver internal module can call the API to send message to
- *             firmware side. For example, you can send a debug command packet.
- *             Or you can send a request for FW to modify RLX4181 LBUS HW bank.
- *             Otherwise, you can change MAC/PHT/RF register by firmware at
- *             run time. We do not support message more than one segment now.
- *
- * Input:      NONE
- *
- * Output:     NONE
- *
- * Return:     NONE
- *
- * Revised History:
- *     When            Who             Remark
- *     05/06/2008      amy             porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-extern rt_status cmpk_message_handle_tx(struct net_device *dev,
-                                       u8 *codevirtualaddress,
-                                       u32 packettype, u32 buffer_len)
-{
-
-       bool        rt_status = true;
-#ifdef RTL8192U
-       return rt_status;
-#else
-       struct r8192_priv   *priv = ieee80211_priv(dev);
-       u16                 frag_threshold;
-       u16                 frag_length, frag_offset = 0;
-
-       rt_firmware         *pfirmware = priv->pFirmware;
-       struct sk_buff      *skb;
-       unsigned char       *seg_ptr;
-       cb_desc             *tcb_desc;
-       u8                  bLastIniPkt;
-
-       firmware_init_param(dev);
-       /* Fragmentation might be required */
-       frag_threshold = pfirmware->cmdpacket_frag_thresold;
-       do {
-               if ((buffer_len - frag_offset) > frag_threshold) {
-                       frag_length = frag_threshold;
-                       bLastIniPkt = 0;
-
-               } else {
-                       frag_length = buffer_len - frag_offset;
-                       bLastIniPkt = 1;
-
-               }
-
-               /* Allocate skb buffer to contain firmware info and tx
-                  descriptor info add 4 to avoid packet appending overflow. */
-#ifdef RTL8192U
-               skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
-#else
-               skb  = dev_alloc_skb(frag_length + 4);
-#endif
-               memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
-               tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-               tcb_desc->queue_index = TXCMD_QUEUE;
-               tcb_desc->bCmdOrInit = packettype;
-               tcb_desc->bLastIniPkt = bLastIniPkt;
-
-#ifdef RTL8192U
-               skb_reserve(skb, USB_HWDESC_HEADER_LEN);
-#endif
-
-               seg_ptr = skb_put(skb, buffer_len);
-               /*
-                * Transform from little endian to big endian
-                * and pending zero
-                */
-               memcpy(seg_ptr, codevirtualaddress, buffer_len);
-               tcb_desc->txbuf_size = (u16)buffer_len;
-
-
-               if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) ||
-                   (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||
-                   (priv->ieee80211->queue_stop)) {
-                       RT_TRACE(COMP_FIRMWARE, "======> tx full!\n");
-                       skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
-               } else {
-                       priv->ieee80211->softmac_hard_start_xmit(skb, dev);
-               }
-
-               codevirtualaddress += frag_length;
-               frag_offset += frag_length;
-
-       } while (frag_offset < buffer_len);
-
-       return rt_status;
-
-
-#endif
-}
-
 /*-----------------------------------------------------------------------------
  * Function:    cmpk_counttxstatistic()
  *
@@ -593,8 +494,8 @@ static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg)
  *  05/06/2008         amy     Create Version 0 porting from windows code.
  *
  *---------------------------------------------------------------------------*/
-extern u32 cmpk_message_handle_rx(struct net_device *dev,
-                                 struct ieee80211_rx_stats *pstats)
+u32 cmpk_message_handle_rx(struct net_device *dev,
+                          struct ieee80211_rx_stats *pstats)
 {
        int                     total_length;
        u8                      cmd_length, exe_cnt = 0;
index ebe403270a5bb5ee7b7efc8c04e50d9a07995ea4..52cd437ef7bb52d058c652ac9594de1e9666b20c 100644 (file)
@@ -1,17 +1,17 @@
 #ifndef R819XUSB_CMDPKT_H
 #define R819XUSB_CMDPKT_H
 /* Different command packet have dedicated message length and definition. */
-#define                CMPK_RX_TX_FB_SIZE                                      sizeof(cmpk_txfb_t)             //20
-#define                CMPK_TX_SET_CONFIG_SIZE                         sizeof(cmpk_set_cfg_t)  //16
-#define                CMPK_BOTH_QUERY_CONFIG_SIZE                     sizeof(cmpk_set_cfg_t)  //16
-#define                CMPK_RX_TX_STS_SIZE                                     sizeof(cmpk_tx_status_t)//
-#define                CMPK_RX_DBG_MSG_SIZE                    sizeof(cmpk_rx_dbginfo_t)//
-#define                CMPK_TX_RAHIS_SIZE                      sizeof(cmpk_tx_rahis_t)
+#define                CMPK_RX_TX_FB_SIZE              sizeof(cmpk_txfb_t)     /* 20 */
+#define                CMPK_TX_SET_CONFIG_SIZE         sizeof(cmpk_set_cfg_t)  /* 16 */
+#define                CMPK_BOTH_QUERY_CONFIG_SIZE     sizeof(cmpk_set_cfg_t)  /* 16 */
+#define                CMPK_RX_TX_STS_SIZE             sizeof(cmpk_tx_status_t)
+#define                CMPK_RX_DBG_MSG_SIZE            sizeof(cmpk_rx_dbginfo_t)
+#define                CMPK_TX_RAHIS_SIZE              sizeof(cmpk_tx_rahis_t)
 
 /* 2008/05/08 amy For USB constant. */
-#define ISR_TxBcnOk                                    BIT27                   // Transmit Beacon OK
-#define ISR_TxBcnErr                           BIT26                   // Transmit Beacon Error
-#define ISR_BcnTimerIntr                       BIT13                   // Beacon Timer Interrupt
+#define ISR_TxBcnOk            BIT27           /* Transmit Beacon OK */
+#define ISR_TxBcnErr           BIT26           /* Transmit Beacon Error */
+#define ISR_BcnTimerIntr       BIT13           /* Beacon Timer Interrupt */
 
 
 /* Define element ID of command packet. */
 /* Define different command packet structure. */
 /* 1. RX side: TX feedback packet. */
 typedef struct tag_cmd_pkt_tx_feedback {
-       // DWORD 0
+       /* DWORD 0 */
        u8      element_id;                     /* Command packet type. */
        u8      length;                         /* Command packet length. */
-       /* 2007/07/05 MH Change tx feedback info field. */
+       /* Change tx feedback info field. */
        /*------TX Feedback Info Field */
-       u8      TID:4;                          /* */
-       u8      fail_reason:3;          /* */
+       u8      TID:4;
+       u8      fail_reason:3;
        u8      tok:1;                          /* Transmit ok. */
-       u8      reserve1:4;                     /* */
-       u8      pkt_type:2;             /* */
-       u8      bandwidth:1;            /* */
-       u8      qos_pkt:1;                      /* */
+       u8      reserve1:4;
+       u8      pkt_type:2;
+       u8      bandwidth:1;
+       u8      qos_pkt:1;
 
-       // DWORD 1
-       u8      reserve2;                       /* */
+       /* DWORD 1 */
+       u8      reserve2;
        /*------TX Feedback Info Field */
-       u8      retry_cnt;                      /* */
-       u16     pkt_id;                         /* */
+       u8      retry_cnt;
+       u16     pkt_id;
 
-       // DWORD 3
-       u16     seq_num;                        /* */
+       /* DWORD 3 */
+       u16     seq_num;
        u8      s_rate;                         /* Start rate. */
        u8      f_rate;                         /* Final rate. */
 
-       // DWORD 4
-       u8      s_rts_rate;                     /* */
-       u8      f_rts_rate;                     /* */
-       u16     pkt_length;                     /* */
+       /* DWORD 4 */
+       u8      s_rts_rate;
+       u8      f_rts_rate;
+       u16     pkt_length;
 
-       // DWORD 5
-       u16     reserve3;                       /* */
-       u16     duration;                       /* */
-}cmpk_txfb_t;
+       /* DWORD 5 */
+       u16     reserve3;
+       u16     duration;
+} cmpk_txfb_t;
 
 /* 2. RX side: Interrupt status packet. It includes Beacon State,
        Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */
* Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */
 typedef struct tag_cmd_pkt_interrupt_status {
        u8      element_id;                     /* Command packet type. */
        u8      length;                         /* Command packet length. */
        u16     reserve;
-       u32     interrupt_status;                               /* Interrupt Status. */
-}cmpk_intr_sta_t;
+       u32     interrupt_status;               /* Interrupt Status. */
+} cmpk_intr_sta_t;
 
 
 /* 3. TX side: Set configuration packet. */
 typedef struct tag_cmd_pkt_set_configuration {
        u8      element_id;                     /* Command packet type. */
        u8      length;                         /* Command packet length. */
-       u16     reserve1;                       /* */
+       u16     reserve1;
+       /* Configuration info. */
        u8      cfg_reserve1:3;
-       u8      cfg_size:2;                     /* Configuration info. */
-       u8      cfg_type:2;                     /* Configuration info. */
-       u8      cfg_action:1;           /* Configuration info. */
-       u8      cfg_reserve2;           /* Configuration info. */
-       u8      cfg_page:4;                     /* Configuration info. */
-       u8      cfg_reserve3:4;         /* Configuration info. */
-       u8      cfg_offset;                     /* Configuration info. */
-       u32     value;                          /* */
-       u32     mask;                           /* */
-}cmpk_set_cfg_t;
+       u8      cfg_size:2;
+       u8      cfg_type:2;
+       u8      cfg_action:1;
+       u8      cfg_reserve2;
+       u8      cfg_page:4;
+       u8      cfg_reserve3:4;
+       u8      cfg_offset;
+       u32     value;
+       u32     mask;
+} cmpk_set_cfg_t;
 
 /* 4. Both side : TX/RX query configuraton packet. The query structure is the
       same as set configuration. */
 #define                cmpk_query_cfg_t        cmpk_set_cfg_t
 
 /* 5. Multi packet feedback status. */
-typedef struct tag_tx_stats_feedback { // PJ quick rxcmd 09042007
-       // For endian transfer --> Driver will not the same as firmware structure.
-       // DW 0
+typedef struct tag_tx_stats_feedback {
+       /* For endian transfer --> Driver will not the same as
+          firmware structure. */
+       /* DW 0 */
        u16     reserve1;
-       u8      length;                         // Command packet length
-       u8      element_id;                     // Command packet type
+       u8      length;                         /* Command packet length */
+       u8      element_id;                     /* Command packet type */
 
-       // DW 1
-       u16     txfail;                         // Tx Fail count
-       u16     txok;                           // Tx ok count
+       /* DW 1 */
+       u16     txfail;                         /* Tx fail count */
+       u16     txok;                           /* Tx ok count */
 
-       // DW 2
-       u16     txmcok;                         // tx multicast
-       u16     txretry;                        // Tx Retry count
+       /* DW 2 */
+       u16     txmcok;                         /* Tx multicast */
+       u16     txretry;                        /* Tx retry count */
 
-       // DW 3
-       u16  txucok;                            // tx unicast
-       u16     txbcok;                         // tx broadcast
+       /* DW 3 */
+       u16     txucok;                         /* Tx unicast */
+       u16     txbcok;                         /* Tx broadcast */
 
-       // DW 4
-       u16     txbcfail;                       //
-       u16     txmcfail;                       //
+       /* DW 4 */
+       u16     txbcfail;
+       u16     txmcfail;
 
-       // DW 5
-       u16     reserve2;                       //
-       u16     txucfail;                       //
+       /* DW 5 */
+       u16     reserve2;
+       u16     txucfail;
 
-       // DW 6-8
+       /* DW 6-8 */
        u32     txmclength;
        u32     txbclength;
        u32     txuclength;
 
-       // DW 9
+       /* DW 9 */
        u16     reserve3_23;
        u8      reserve3_1;
        u8      rate;
-}__attribute__((packed)) cmpk_tx_status_t;
+} __packed cmpk_tx_status_t;
 
 /* 6. Debug feedback message. */
-/* 2007/10/23 MH Define RX debug message  */
+/* Define RX debug message  */
 typedef struct tag_rx_debug_message_feedback {
-       // For endian transfer --> for driver
-       // DW 0
+       /* For endian transfer --> for driver */
+       /* DW 0 */
        u16     reserve1;
-       u8      length;                         // Command packet length
-       u8      element_id;                     // Command packet type
+       u8      length;                         /* Command packet length */
+       u8      element_id;                     /* Command packet type */
 
-       // DW 1-??
-       // Variable debug message.
+       /* DW 1-?? */
+       /* Variable debug message. */
 
-}cmpk_rx_dbginfo_t;
+} cmpk_rx_dbginfo_t;
 
-/* 2008/03/20 MH Define transmit rate history. For big endian format. */
+/* Define transmit rate history. For big endian format. */
 typedef struct tag_tx_rate_history {
-       // For endian transfer --> for driver
-       // DW 0
-       u8      element_id;                     // Command packet type
-       u8      length;                         // Command packet length
+       /* For endian transfer --> for driver */
+       /* DW 0 */
+       u8      element_id;                     /* Command packet type */
+       u8      length;                         /* Command packet length */
        u16     reserved1;
 
-       // DW 1-2       CCK rate counter
+       /* DW 1-2       CCK rate counter */
        u16     cck[4];
 
-       // DW 3-6
+       /* DW 3-6 */
        u16     ofdm[8];
 
-       // DW 7-14
-       //UINT16        MCS_BW0_SG0[16];
-
-       // DW 15-22
-       //UINT16        MCS_BW1_SG0[16];
-
-       // DW 23-30
-       //UINT16        MCS_BW0_SG1[16];
-
-       // DW 31-38
-       //UINT16        MCS_BW1_SG1[16];
-
-       // DW 7-14      BW=0 SG=0
-       // DW 15-22     BW=1 SG=0
-       // DW 23-30     BW=0 SG=1
-       // DW 31-38     BW=1 SG=1
+       /* DW 7-14      BW=0 SG=0
+        * DW 15-22     BW=1 SG=0
+        * DW 23-30     BW=0 SG=1
+        * DW 31-38     BW=1 SG=1
+        */
        u16     ht_mcs[4][16];
 
-}__attribute__((packed)) cmpk_tx_rahis_t;
-
-typedef enum tag_command_packet_directories
-{
-    RX_TX_FEEDBACK = 0,
-    RX_INTERRUPT_STATUS                = 1,
-    TX_SET_CONFIG                              = 2,
-    BOTH_QUERY_CONFIG                  = 3,
-    RX_TX_STATUS                               = 4,
-    RX_DBGINFO_FEEDBACK                = 5,
-    RX_TX_PER_PKT_FEEDBACK             = 6,
-    RX_TX_RATE_HISTORY         = 7,
-    RX_CMD_ELE_MAX
-}cmpk_element_e;
-
-typedef enum _rt_status{
+} __packed cmpk_tx_rahis_t;
+
+typedef enum tag_command_packet_directories {
+       RX_TX_FEEDBACK                  = 0,
+       RX_INTERRUPT_STATUS             = 1,
+       TX_SET_CONFIG                   = 2,
+       BOTH_QUERY_CONFIG               = 3,
+       RX_TX_STATUS                    = 4,
+       RX_DBGINFO_FEEDBACK             = 5,
+       RX_TX_PER_PKT_FEEDBACK          = 6,
+       RX_TX_RATE_HISTORY              = 7,
+       RX_CMD_ELE_MAX
+} cmpk_element_e;
+
+typedef enum _rt_status {
        RT_STATUS_SUCCESS,
        RT_STATUS_FAILURE,
        RT_STATUS_PENDING,
        RT_STATUS_RESOURCE
-}rt_status,*prt_status;
-
-extern rt_status cmpk_message_handle_tx(struct net_device *dev, u8 *codevirtualaddress, u32 packettype, u32 buffer_len);
+} rt_status, *prt_status;
 
-extern  u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *pstats);
-extern rt_status SendTxCommandPacket( struct net_device *dev, void *pData, u32 DataLen);
+extern u32 cmpk_message_handle_rx(struct net_device *dev,
+               struct ieee80211_rx_stats *pstats);
+extern rt_status SendTxCommandPacket(struct net_device *dev,
+               void *pData, u32 DataLen);
 
 
 #endif
index bb924ac97e471d9e5613666a18b6f8acb6c0a151..d6a6de3a64f5d6cfd4869f4879293d710ddabf2b 100644 (file)
@@ -61,20 +61,16 @@ bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, u32 buff
                /* Allocate skb buffer to contain firmware info and tx descriptor info
                 * add 4 to avoid packet appending overflow.
                 * */
-               #ifdef RTL8192U
                skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
-               #else
-               skb  = dev_alloc_skb(frag_length + 4);
-               #endif
+               if (!skb)
+                       return false;
                memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
                tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
                tcb_desc->queue_index = TXCMD_QUEUE;
                tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
                tcb_desc->bLastIniPkt = bLastIniPkt;
 
-               #ifdef RTL8192U
                skb_reserve(skb, USB_HWDESC_HEADER_LEN);
-               #endif
                seg_ptr = skb->data;
                /*
                 * Transform from little endian to big endian
@@ -299,16 +295,10 @@ bool init_firmware(struct net_device *dev)
                                mapped_file = pfirmware->firmware_buf;
                                file_length = fw_entry->size;
                        } else {
-#ifdef RTL8190P
-                               memcpy(pfirmware->firmware_buf,fw_entry->data,fw_entry->size);
-                               mapped_file = pfirmware->firmware_buf;
-                               file_length = fw_entry->size;
-#else
                                memset(pfirmware->firmware_buf,0,128);
                                memcpy(&pfirmware->firmware_buf[128],fw_entry->data,fw_entry->size);
                                mapped_file = pfirmware->firmware_buf;
                                file_length = fw_entry->size + 128;
-#endif
                        }
                        pfirmware->firmware_buf_size = file_length;
                }else if (rst_opt == OPT_FIRMWARE_RESET ) {
@@ -340,15 +330,6 @@ bool init_firmware(struct net_device *dev)
                         * will set polling bit when firmware code is also configured
                         */
                        pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE;
-#ifdef RTL8190P
-                       // To initialize IMEM, CPU move code  from 0x80000080, hence, we send 0x80 byte packet
-                       rt_status = fwSendNullPacket(dev, RTL8190_CPU_START_OFFSET);
-                       if (rt_status != true)
-                       {
-                               RT_TRACE(COMP_INIT, "fwSendNullPacket() fail ! \n");
-                               goto  download_firmware_fail;
-                       }
-#endif
                        //mdelay(1000);
                        /*
                         * To initialize IMEM, CPU move code  from 0x80000080,
index a6fac081e42c121accca043899bee3a033b772a5..39cd426bc5e5e92adf49c21ff8b7de004bb3b9ad 100644 (file)
@@ -1713,7 +1713,7 @@ void InitialGain819xUsb(struct net_device *dev,   u8 Operation)
                queue_delayed_work(priv->priv_wq, &priv->initialgain_operate_wq, 0);
 }
 
-extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
+void InitialGainOperateWorkItemCallBack(struct work_struct *work)
 {
        struct delayed_work *dwork = container_of(work, struct delayed_work,
                                                  work);
@@ -1799,12 +1799,6 @@ extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
                RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",
                         priv->initgain_backup.cca);
 
-#ifdef RTL8190P
-               SetTxPowerLevel8190(Adapter, priv->CurrentChannel);
-#endif
-#ifdef RTL8192E
-               SetTxPowerLevel8190(Adapter, priv->CurrentChannel);
-#endif
                rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel);
 
                if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
index f3c352a10fe06965a5281e0c12268fea5c172621..66cbe3f9cafd9116e42ea7a47be0fc16637288f0 100644 (file)
@@ -23,7 +23,7 @@ typedef struct _SwChnlCmd {
        u32             Para1;
        u32             Para2;
        u32             msDelay;
-} __attribute__ ((packed)) SwChnlCmd;
+} __packed SwChnlCmd;
 
 extern u32 rtl819XMACPHY_Array_PG[];
 extern u32 rtl819XPHY_REG_1T2RArray[];
index 6e81ba0eaf1e5542346c7a04121333d4193aedc4..82a77b45fb50901df1bfb0aba005da9375313517 100644 (file)
@@ -141,7 +141,7 @@ static uint loadparam(struct _adapter *padapter, struct  net_device *pnetdev)
        registry_par->ssid.SsidLength = 3;
        registry_par->channel = (u8)channel;
        registry_par->wireless_mode = (u8)wireless_mode;
-       registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense ;
+       registry_par->vrtl_carrier_sense = (u8)vrtl_carrier_sense;
        registry_par->vcs_type = (u8)vcs_type;
        registry_par->frag_thresh = (u16)frag_thresh;
        registry_par->preamble = (u8)preamble;
index 088647cdca9953cd47783c4ac41cdbfed9cac512..5b6a96e3bd7b15db5f8c2a34fc9dc592a61fd2cd 100644 (file)
@@ -62,7 +62,7 @@ static void check_hw_pbc(struct _adapter *padapter)
        r8712_write8(padapter, GPIO_IO_SEL, tmp1byte);
        tmp1byte = r8712_read8(padapter, GPIO_CTRL);
        if (tmp1byte == 0xff)
-               return ;
+               return;
        if (tmp1byte&HAL_8192S_HW_GPIO_WPS_BIT) {
                /* Here we only set bPbcPressed to true
                 * After trigger PBC, the variable will be set to false */
@@ -381,7 +381,7 @@ _next:
                        *pcmdbuf = cpu_to_le32((cmdsz & 0x0000ffff) |
                                               (pcmd->cmdcode << 16) |
                                               (pcmdpriv->cmd_seq << 24));
-                       pcmdbuf += 2 ; /* 8 bytes alignment */
+                       pcmdbuf += 2; /* 8 bytes alignment */
                        memcpy((u8 *)pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
                        while (check_cmd_fifo(padapter, wr_sz) == _FAIL) {
                                if ((padapter->bDriverStopped == true) ||
@@ -471,11 +471,9 @@ void r8712_event_handle(struct _adapter *padapter, uint *peventbuf)
        if (pevt_priv->event_seq > 127)
                pevt_priv->event_seq = 0;
        peventbuf = peventbuf + 2; /* move to event content, 8 bytes alignment */
-       if (peventbuf) {
-               event_callback = wlanevents[evt_code].event_callback;
-               if (event_callback)
-                       event_callback(padapter, (u8 *)peventbuf);
-       }
+       event_callback = wlanevents[evt_code].event_callback;
+       if (event_callback)
+               event_callback(padapter, (u8 *)peventbuf);
        pevt_priv->evt_done_cnt++;
 _abort_event_:
        return;
index 377fca905801aa974749ac9943d13efee51d5bec..c9eeb4270ab9d84e4a8619d8f4d9270bfe9ba085 100644 (file)
@@ -231,7 +231,7 @@ u16 r8712_efuse_get_current_size(struct _adapter *padapter)
                        /* read next header */
                        efuse_addr = efuse_addr + (word_cnts * 2) + 1;
                } else
-                       bContinual = false ;
+                       bContinual = false;
        }
        return efuse_addr;
 }
index d59a74aa30489f2bf70c9f6b8a450d8ddaf4b484..ea965370d1ac9ed0bc5520721532b8d15419adfd 100644 (file)
@@ -108,7 +108,7 @@ void r8712_free_recv_priv(struct recv_priv *precvpriv)
        struct _adapter *padapter = precvpriv->adapter;
 
        precvbuf = (struct recv_buf *)precvpriv->precv_buf;
-       for (i = 0; i < NR_RECVBUFF ; i++) {
+       for (i = 0; i < NR_RECVBUFF; i++) {
                r8712_os_recvbuf_resource_free(padapter, precvbuf);
                precvbuf++;
        }
@@ -268,7 +268,7 @@ union recv_frame *r8712_recvframe_chk_defrag(struct _adapter *padapter,
        u8   *psta_addr;
        struct recv_frame_hdr *pfhdr;
        struct sta_info *psta;
-       struct  sta_priv *pstapriv ;
+       struct  sta_priv *pstapriv;
        struct list_head *phead;
        union recv_frame *prtnframe = NULL;
        struct  __queue *pfree_recv_queue, *pdefrag_q;
@@ -849,7 +849,7 @@ static void query_rx_phy_status(struct _adapter *padapter,
        } else {
                /* (1)Get RSSI for HT rate */
                for (i = 0; i < ((padapter->registrypriv.rf_config) &
-                           0x0f) ; i++) {
+                           0x0f); i++) {
                        rf_rx_num++;
                        rx_pwr[i] = ((pphy_head[PHY_STAT_GAIN_TRSW_SHT + i]
                                    & 0x3F) * 2) - 110;
index f16307f5d827e72707996c1299c8636e3448e000..7e324315e6ad30846166b9ea9a5bd0f2662e349a 100644 (file)
@@ -965,7 +965,7 @@ void r8712_createbss_cmd_callback(struct _adapter *padapter,
                        psta = r8712_alloc_stainfo(&padapter->stapriv,
                                                   pnetwork->MacAddress);
                        if (psta == NULL)
-                               goto createbss_cmd_fail ;
+                               goto createbss_cmd_fail;
                }
                r8712_indicate_connect(padapter);
        } else {
index d58aa7e3b15cef799726d8bb4f4e656ddfaf7c91..9fec6eda8731c91612f038b370d5258b7adc6c3c 100644 (file)
@@ -820,7 +820,7 @@ static int r871x_wx_set_pmkid(struct net_device *dev,
                        intReturn = true;
                blInserted = false;
                /* overwrite PMKID */
-               for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
+               for (j = 0; j < NUM_PMKID_CACHE; j++) {
                        if (!memcmp(psecuritypriv->PMKIDList[j].Bssid,
                            strIssueBssid, ETH_ALEN)) {
                                /* BSSID is matched, the same AP => rewrite
@@ -845,7 +845,7 @@ static int r871x_wx_set_pmkid(struct net_device *dev,
                                PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
                        psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
                                bUsed = true;
-                       psecuritypriv->PMKIDIndex++ ;
+                       psecuritypriv->PMKIDIndex++;
                        if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE)
                                psecuritypriv->PMKIDIndex = 0;
                }
@@ -1598,7 +1598,7 @@ static int r8711_wx_set_enc(struct net_device *dev,
                wep.Length = wep.KeyLength +
                             FIELD_OFFSET(struct NDIS_802_11_WEP, KeyMaterial);
        } else {
-               wep.KeyLength = 0 ;
+               wep.KeyLength = 0;
                if (keyindex_provided == 1) { /* set key_id only, no given
                                               * KeyMaterial(erq->length==0).*/
                        padapter->securitypriv.PrivacyKeyIndex = key;
@@ -1880,7 +1880,7 @@ static int r8711_wx_write32(struct net_device *dev,
        u32 data32;
 
        get_user(addr, (u32 __user *)wrqu->data.pointer);
-       data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags ;
+       data32 = ((u32)wrqu->data.length<<16) | (u32)wrqu->data.flags;
        r8712_write32(padapter, addr, data32);
        return 0;
 }
index 5d6d55e7b38909d316b4ffa4528b5037170072ed..ac0baff7f090e5f12e9d552fb8162ec4d398e2f2 100644 (file)
@@ -153,7 +153,7 @@ uint oid_rt_get_rx_icv_err_hdl(struct oid_par_priv *poid_par_priv)
                                         padapter->recvpriv.rx_icv_err;
                *poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
        } else
-               return RNDIS_STATUS_INVALID_LENGTH ;
+               return RNDIS_STATUS_INVALID_LENGTH;
        return RNDIS_STATUS_SUCCESS;
 }
 
@@ -169,7 +169,7 @@ uint oid_rt_get_preamble_mode_hdl(struct oid_par_priv *poid_par_priv)
 {
        struct _adapter *padapter = (struct _adapter *)
                                    (poid_par_priv->adapter_context);
-       u32 preamblemode = 0 ;
+       u32 preamblemode = 0;
 
        if (poid_par_priv->type_of_oid != QUERY_OID)
                return RNDIS_STATUS_NOT_ACCEPTED;
@@ -522,7 +522,7 @@ uint oid_rt_get_connect_state_hdl(struct oid_par_priv *poid_par_priv)
        else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)
                ulInfo = ADHOCMODE;
        else
-               ulInfo = NOTASSOCIATED ;
+               ulInfo = NOTASSOCIATED;
        *(u32 *)poid_par_priv->information_buf = ulInfo;
        *poid_par_priv->bytes_rw =  poid_par_priv->information_buf_len;
        return RNDIS_STATUS_SUCCESS;
index 659615481f6f4c1b8d387c572cc063a11cd9492c..8fa0f9d49a8aedb6800d25e07b004a61c4a18531 100644 (file)
@@ -1641,7 +1641,7 @@ void r8712_update_registrypriv_dev_network(struct _adapter *adapter)
        struct wlan_network     *cur_network = &adapter->mlmepriv.cur_network;
 
        pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm
-                                           > 0 ? 1 : 0) ; /* adhoc no 802.1x */
+                                           > 0 ? 1 : 0); /* adhoc no 802.1x */
        pdev_network->Rssi = 0;
        switch (pregistrypriv->wireless_mode) {
        case WIRELESS_11B:
@@ -1786,7 +1786,7 @@ static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len)
        psta = r8712_get_stainfo(&padapter->stapriv,
                                 pcur_network->network.MacAddress);
        if (psta) {
-               for (i = 0; i < 16 ; i++) {
+               for (i = 0; i < 16; i++) {
                        preorder_ctrl = &psta->recvreorder_ctrl[i];
                        preorder_ctrl->indicate_seq = 0xffff;
                        preorder_ctrl->wend_b = 0xffff;
index 5638d5e065ff7a05c919712040abb9300adcb16f..0563318a19ff40962984dd8b3094f34c3680ec29 100644 (file)
@@ -110,7 +110,7 @@ static u32 fw_iocmd_read(struct _adapter *pAdapter, struct IOCMD_STRUCT iocmd)
        u16 iocmd_value = iocmd.value;
        u8 iocmd_idx    = iocmd.index;
 
-       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx ;
+       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx;
        if (r8712_fw_cmd(pAdapter, cmd32))
                r8712_fw_cmd_data(pAdapter, &val32, 1);
        else
@@ -128,7 +128,7 @@ static u8 fw_iocmd_write(struct _adapter *pAdapter,
 
        r8712_fw_cmd_data(pAdapter, &value, 0);
        msleep(100);
-       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx ;
+       cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx;
        return r8712_fw_cmd(pAdapter, cmd32);
 }
 
@@ -189,8 +189,8 @@ u32 r8712_rf_reg_read(struct _adapter *pAdapter, u8 path, u8 offset)
        u32 rf_data;
        struct IOCMD_STRUCT iocmd;
 
-       iocmd.cmdclass  = IOCMD_CLASS_BB_RF ;
-       iocmd.value     = rf_addr ;
+       iocmd.cmdclass  = IOCMD_CLASS_BB_RF;
+       iocmd.value     = rf_addr;
        iocmd.index     = IOCMD_RF_READ_IDX;
        rf_data = fw_iocmd_read(pAdapter, iocmd);
        return rf_data;
index e33fd6db246d9e80bd43aa732a2c86c23f2e1444..5349669707c04d7785564cfd1e153a90ff6e8578 100644 (file)
@@ -835,7 +835,7 @@ static void mix_column(u8 *in, u8 *out)
        u8 temp[4];
        u8 tempb[4];
 
-       for (i = 0 ; i < 4; i++) {
+       for (i = 0; i < 4; i++) {
                if ((in[i] & 0x80) == 0x80)
                        add1b[i] = 0x1b;
                else
@@ -1187,7 +1187,7 @@ u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe)
                                        length = pxmitpriv->frag_len -
                                                 pattrib->hdrlen -
                                                 pattrib->iv_len -
-                                                pattrib->icv_len ;
+                                                pattrib->icv_len;
                                        aes_cipher(prwskey, pattrib->
                                                   hdrlen, pframe, length);
                                        pframe += pxmitpriv->frag_len;
@@ -1315,7 +1315,7 @@ static sint aes_decipher(u8 *key, uint    hdrlen,
                bitwise_xor(aes_out, padded_buffer, chain_buffer);
                aes128k128d(key, chain_buffer, aes_out);
        }
-       for (j = 0 ; j < 8; j++)
+       for (j = 0; j < 8; j++)
                mic[j] = aes_out[j];
        /* Insert MIC into payload */
        for (j = 0; j < 8; j++)
index 1247b3d9719db5f279e770bbf8cd2234d38cc7be..8db6849d4b24a0f35e438a0bf369dd9c69833465 100644 (file)
@@ -138,7 +138,7 @@ struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
                }
                phash_list = &(pstapriv->sta_hash[index]);
                list_insert_tail(&psta->hash_list, phash_list);
-               pstapriv->asoc_sta_count++ ;
+               pstapriv->asoc_sta_count++;
 
 /* For the SMC router, the sequence number of first packet of WPS handshake
  * will be 0. In this case, this packet will be dropped by recv_decache function
@@ -149,7 +149,7 @@ struct sta_info *r8712_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
                        memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i],
                                &wRxSeqInitialValue, 2);
                /* for A-MPDU Rx reordering buffer control */
-               for (i = 0; i < 16 ; i++) {
+               for (i = 0; i < 16; i++) {
                        preorder_ctrl = &psta->recvreorder_ctrl[i];
                        preorder_ctrl->padapter = pstapriv->padapter;
                        preorder_ctrl->indicate_seq = 0xffff;
index c812d6c7dc31d48b8c9fc320ce59fba2d735f89a..dbefa43e4c2c50211cf4aa866896d875068b8147 100644 (file)
@@ -353,11 +353,6 @@ static void disable_ht_for_spec_devid(const struct usb_device_id *pdid,
        }
 }
 
-static u8 key_2char2num(u8 hch, u8 lch)
-{
-       return (hex_to_bin(hch) << 4) | hex_to_bin(lch);
-}
-
 /*
  * drv_init() - a device potentially for us
  *
@@ -465,16 +460,7 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
                                r8712_efuse_pg_packet_read(padapter, offset,
                                                     &pdata[i]);
 
-                       if (r8712_initmac) {
-                               /* Users specify the mac address */
-                               int jj, kk;
-
-                               for (jj = 0, kk = 0; jj < ETH_ALEN;
-                                    jj++, kk += 3)
-                                       mac[jj] =
-                                          key_2char2num(r8712_initmac[kk],
-                                          r8712_initmac[kk + 1]);
-                       } else {
+                       if (!r8712_initmac || !mac_pton(r8712_initmac, mac)) {
                                /* Use the mac address stored in the Efuse
                                 * offset = 0x12 for usb in efuse
                                 */
index 4d22bb7008f8456e378c3568d3252be7ede9a79f..0ac9130faf6cad9cb298e8b8a44e9863a81328cf 100644 (file)
@@ -51,7 +51,7 @@ void _r8712_open_pktfile(_pkt *pktptr, struct pkt_file *pfile)
        pfile->pkt = pktptr;
        pfile->cur_addr = pfile->buf_start = pktptr->data;
        pfile->pkt_len = pfile->buf_len = pktptr->len;
-       pfile->cur_buffer = pfile->buf_start ;
+       pfile->cur_buffer = pfile->buf_start;
 }
 
 uint _r8712_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen)
index 304e1bcd1e3b2c78f89704ee2e65c2da353163ee..16de497415eebaf70728eac603490c9ccdd2ee5a 100644 (file)
@@ -15,8 +15,8 @@
 #ifndef UART_SB105X_H
 #define UART_SB105X_H
 
-/* 
- * option register 
+/*
+ * option register
  */
 
 /* Device Information Register */
index 23db32f07fd533ac4803b9a0a56815a5a7606eea..adb6bea728b2cead75af2ecec5997d4e3c011cf5 100644 (file)
@@ -1808,10 +1808,7 @@ void mp_unregister_driver(struct uart_driver *drv)
     drv->tty_driver = NULL;
 
 
-    if (drv->state)
-    {
-        kfree(drv->state);
-    }
+    kfree(drv->state);
 
 }
 
index 490a31e0fd4345369028380ef4f94ac3d40b481a..b9262a78dd6edd2e24f6894b5909030262741543 100644 (file)
@@ -1134,7 +1134,7 @@ static int sep_crypto_block_data(struct ablkcipher_request *req)
 
        if (int_error < 0) {
                dev_warn(&ta_ctx->sep_used->pdev->dev, "oddball page error\n");
-               return -ENOMEM;
+               return int_error;
        } else if (int_error == 1) {
                ta_ctx->src_sg = new_sg;
                ta_ctx->src_sg_hold = new_sg;
@@ -1149,7 +1149,7 @@ static int sep_crypto_block_data(struct ablkcipher_request *req)
        if (int_error < 0) {
                dev_warn(&ta_ctx->sep_used->pdev->dev, "walk phys error %x\n",
                        int_error);
-               return -ENOMEM;
+               return int_error;
        } else if (int_error == 1) {
                ta_ctx->dst_sg = new_sg;
                ta_ctx->dst_sg_hold = new_sg;
index 6a98a208bbf2895b0a978cd10658edf7e7f51ae0..11f5b211745758bb42dd6eb2190620282109ea1c 100644 (file)
@@ -1263,13 +1263,8 @@ static int sep_lock_user_pages(struct sep_device *sep,
        }
 
        /* Convert the application virtual address into a set of physical */
-       down_read(&current->mm->mmap_sem);
-       result = get_user_pages(current, current->mm, app_virt_addr,
-               num_pages,
-               ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1),
-               0, page_array, NULL);
-
-       up_read(&current->mm->mmap_sem);
+       result = get_user_pages_fast(app_virt_addr, num_pages,
+               ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1), page_array);
 
        /* Check the number of pages locked - if not all then exit with error */
        if (result != num_pages) {
index cfa1f43fa4af08a6ffaa4d09a0d9202458c15ece..8154a7bf050fe7a1d7607e80bdbc889669b3b972 100644 (file)
@@ -22,7 +22,7 @@ do {                                          \
        int  i;                                 \
        if (1) {                                \
                for (i = 0; i < 1000; i++) {    \
-                       udelay(x) ;             \
+                       udelay(x)             \
                }                               \
        } else {                                \
                msleep(x);                      \
index 495272d0134859bf36f080bd7a5c53bc5e0ae708..39dc92a271aba2a1f341a224bd59089fa2ba3870 100644 (file)
@@ -1,11 +1,11 @@
 /******************************************************************************/
 /*                                                                            */
-/* Bypass Control utility, Copyright (c) 2005-20011 Silicom                   */
+/* Bypass Control utility, Copyright (c) 2005-2011 Silicom                    */
 /*                                                                            */
 /* 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, located in the file LICENSE.                 */
-/*  Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.          */
+/* Copyright(c) 2007 - 2009, 2013 Intel Corporation. All rights reserved.     */
 /*                                                                            */
 /*                                                                            */
 /******************************************************************************/
@@ -124,80 +124,60 @@ int bp_proc_create(void);
 int is_bypass_fn(struct bpctl_dev *pbpctl_dev);
 int get_dev_idx_bsf(int bus, int slot, int func);
 
-static unsigned long str_to_hex(char *p);
+static int bp_get_dev_idx_bsf(struct net_device *dev, int *index)
+{
+       struct ethtool_drvinfo drvinfo = {0};
+       char *buf;
+       int bus, slot, func;
+
+       if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo)
+               dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
+       else
+               return -EOPNOTSUPP;
+
+       if (!drvinfo.bus_info)
+               return -ENODATA;
+       if (!strcmp(drvinfo.bus_info, "N/A"))
+               return -ENODATA;
+
+       buf = strchr(drvinfo.bus_info, ':');
+       if (!buf)
+               return -EINVAL;
+       buf++;
+       if (sscanf(buf, "%x:%x.%x", &bus, &slot, &func) != 3)
+               return -EINVAL;
+
+       *index = get_dev_idx_bsf(bus, slot, func);
+       return 0;
+}
+
 static int bp_device_event(struct notifier_block *unused,
                           unsigned long event, void *ptr)
 {
        struct net_device *dev = netdev_notifier_info_to_dev(ptr);
        static struct bpctl_dev *pbpctl_dev, *pbpctl_dev_m;
        int dev_num = 0, ret = 0, ret_d = 0, time_left = 0;
+
        /* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */
        /* return NOTIFY_DONE; */
        if (!dev)
                return NOTIFY_DONE;
-       if (event == NETDEV_REGISTER) {
-               {
-                       struct ethtool_drvinfo drvinfo;
-                       char cbuf[32];
-                       char *buf = NULL;
-                       char res[10];
-                       int i = 0, ifindex, idx_dev = 0;
-                       int bus = 0, slot = 0, func = 0;
-                       ifindex = dev->ifindex;
-
-                       memset(res, 0, 10);
-                       memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
-
-                       if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
-                               memset(&drvinfo, 0, sizeof(drvinfo));
-                               dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
-                       } else
-                               return NOTIFY_DONE;
-                       if (!drvinfo.bus_info)
-                               return NOTIFY_DONE;
-                       if (!strcmp(drvinfo.bus_info, "N/A"))
-                               return NOTIFY_DONE;
-                       memcpy(&cbuf, drvinfo.bus_info, 32);
-                       buf = &cbuf[0];
 
-                       while (*buf++ != ':')
-                               ;
-                       for (i = 0; i < 10; i++, buf++) {
-                               if (*buf == ':')
-                                       break;
-                               res[i] = *buf;
-
-                       }
-                       buf++;
-                       bus = str_to_hex(res);
-                       memset(res, 0, 10);
-
-                       for (i = 0; i < 10; i++, buf++) {
-                               if (*buf == '.')
-                                       break;
-                               res[i] = *buf;
-
-                       }
-                       buf++;
-                       slot = str_to_hex(res);
-                       func = str_to_hex(buf);
-                       idx_dev = get_dev_idx_bsf(bus, slot, func);
-
-                       if (idx_dev != -1) {
+       if (event == NETDEV_REGISTER) {
+               int idx_dev;
 
-                               bpctl_dev_arr[idx_dev].ifindex = ifindex;
-                               bpctl_dev_arr[idx_dev].ndev = dev;
+               if (bp_get_dev_idx_bsf(dev, &idx_dev))
+                       return NOTIFY_DONE;
 
-                               bypass_proc_remove_dev_sd(&bpctl_dev_arr
-                                                         [idx_dev]);
-                               bypass_proc_create_dev_sd(&bpctl_dev_arr
-                                                         [idx_dev]);
+               if (idx_dev == -1)
+                       return NOTIFY_DONE;
 
-                       }
+               bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
+               bpctl_dev_arr[idx_dev].ndev = dev;
 
-               }
+               bypass_proc_remove_dev_sd(&bpctl_dev_arr[idx_dev]);
+               bypass_proc_create_dev_sd(&bpctl_dev_arr[idx_dev]);
                return NOTIFY_DONE;
-
        }
        if (event == NETDEV_UNREGISTER) {
                int idx_dev = 0;
@@ -5269,36 +5249,6 @@ int get_dev_idx_bsf(int bus, int slot, int func)
        return -1;
 }
 
-static void str_low(char *str)
-{
-       int i;
-
-       for (i = 0; i < strlen(str); i++)
-               if ((str[i] >= 65) && (str[i] <= 90))
-                       str[i] += 32;
-}
-
-static unsigned long str_to_hex(char *p)
-{
-       unsigned long hex = 0;
-       unsigned long length = strlen(p), shift = 0;
-       unsigned char dig = 0;
-
-       str_low(p);
-       length = strlen(p);
-
-       if (length == 0)
-               return 0;
-
-       do {
-               dig = p[--length];
-               dig = dig < 'a' ? (dig - '0') : (dig - 'a' + 0xa);
-               hex |= (dig << shift);
-               shift += 4;
-       } while (length);
-       return hex;
-}
-
 static int get_dev_idx(int ifindex)
 {
        int idx_dev = 0;
@@ -5329,70 +5279,26 @@ static struct bpctl_dev *get_dev_idx_p(int ifindex)
 
 static void if_scan_init(void)
 {
-       int idx_dev = 0;
        struct net_device *dev;
-       int ifindex;
+
        /* rcu_read_lock(); */
        /* rtnl_lock();     */
        /* rcu_read_lock(); */
 
        for_each_netdev(&init_net, dev) {
+               int idx_dev;
 
-               struct ethtool_drvinfo drvinfo;
-               char cbuf[32];
-               char *buf = NULL;
-               char res[10];
-               int i = 0;
-               int bus = 0, slot = 0, func = 0;
-               ifindex = dev->ifindex;
-
-               memset(res, 0, 10);
-               memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
-
-               if (dev->ethtool_ops && dev->ethtool_ops->get_drvinfo) {
-                       memset(&drvinfo, 0, sizeof(drvinfo));
-                       dev->ethtool_ops->get_drvinfo(dev, &drvinfo);
-               } else
+               if (bp_get_dev_idx_bsf(dev, &idx_dev))
                        continue;
-               if (!strcmp(drvinfo.bus_info, "N/A"))
-                       continue;
-               memcpy(&cbuf, drvinfo.bus_info, 32);
-               buf = &cbuf[0];
 
-               while (*buf++ != ':')
-                       ;
-               for (i = 0; i < 10; i++, buf++) {
-                       if (*buf == ':')
-                               break;
-                       res[i] = *buf;
-
-               }
-               buf++;
-               bus = str_to_hex(res);
-               memset(res, 0, 10);
-
-               for (i = 0; i < 10; i++, buf++) {
-                       if (*buf == '.')
-                               break;
-                       res[i] = *buf;
-
-               }
-               buf++;
-               slot = str_to_hex(res);
-               func = str_to_hex(buf);
-               idx_dev = get_dev_idx_bsf(bus, slot, func);
-
-               if (idx_dev != -1) {
-
-                       bpctl_dev_arr[idx_dev].ifindex = ifindex;
-                       bpctl_dev_arr[idx_dev].ndev = dev;
-
-               }
+               if (idx_dev == -1)
+                       continue;
 
+               bpctl_dev_arr[idx_dev].ifindex = dev->ifindex;
+               bpctl_dev_arr[idx_dev].ndev = dev;
        }
        /* rtnl_unlock();     */
        /* rcu_read_unlock(); */
-
 }
 
 static long device_ioctl(struct file *file,    /* see include/linux/fs.h */
index 869dcd3b385accb8606d8f53c73b298986c4712c..8b5490b4efab71de56576f8d1351a3cd3772034f 100644 (file)
@@ -62,6 +62,7 @@
 #define SLIC_OFFLOAD_IP_CHECKSUM               1
 #define STATS_TIMER_INTERVAL                   2
 #define PING_TIMER_INTERVAL                        1
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -791,8 +792,8 @@ static bool slic_mac_filter(struct adapter *adapter,
                        struct mcast_address *mcaddr = adapter->mcastaddrs;
 
                        while (mcaddr) {
-                               if (!compare_ether_addr(mcaddr->address,
-                                                       ether_frame->ether_dhost)) {
+                               if (ether_addr_equal(mcaddr->address,
+                                                    ether_frame->ether_dhost)) {
                                        adapter->rcv_multicasts++;
                                        netdev->stats.multicast++;
                                        return true;
@@ -2231,14 +2232,8 @@ static void slic_debug_card_destroy(struct sliccard *card)
                if (adapter)
                        slic_debug_adapter_destroy(adapter);
        }
-       if (card->debugfs_cardinfo) {
-               debugfs_remove(card->debugfs_cardinfo);
-               card->debugfs_cardinfo = NULL;
-       }
-       if (card->debugfs_dir) {
-               debugfs_remove(card->debugfs_dir);
-               card->debugfs_dir = NULL;
-       }
+       debugfs_remove(card->debugfs_cardinfo);
+       debugfs_remove(card->debugfs_dir);
 }
 
 static void slic_debug_init(void)
@@ -2256,10 +2251,7 @@ static void slic_debug_init(void)
 
 static void slic_debug_cleanup(void)
 {
-       if (slic_debugfs) {
-               debugfs_remove(slic_debugfs);
-               slic_debugfs = NULL;
-       }
+       debugfs_remove(slic_debugfs);
 }
 
 /*
@@ -2333,7 +2325,7 @@ static int slic_mcast_add_list(struct adapter *adapter, char *address)
        /* Check to see if it already exists */
        mlist = adapter->mcastaddrs;
        while (mlist) {
-               if (!compare_ether_addr(mlist->address, address))
+               if (ether_addr_equal(mlist->address, address))
                        return 0;
                mlist = mlist->next;
        }
@@ -2627,6 +2619,67 @@ static void slic_xmit_complete(struct adapter *adapter)
        adapter->max_isr_xmits = max(adapter->max_isr_xmits, frames);
 }
 
+static void slic_interrupt_card_up(u32 isr, struct adapter *adapter,
+                       struct net_device *dev)
+{
+       if (isr & ~ISR_IO) {
+               if (isr & ISR_ERR) {
+                       adapter->error_interrupts++;
+                       if (isr & ISR_RMISS) {
+                               int count;
+                               int pre_count;
+                               int errors;
+
+                               struct slic_rcvqueue *rcvq =
+                                       &adapter->rcvqueue;
+
+                               adapter->error_rmiss_interrupts++;
+
+                               if (!rcvq->errors)
+                                       rcv_count = rcvq->count;
+                               pre_count = rcvq->count;
+                               errors = rcvq->errors;
+
+                               while (rcvq->count < SLIC_RCVQ_FILLTHRESH) {
+                                       count = slic_rcvqueue_fill(adapter);
+                                       if (!count)
+                                               break;
+                               }
+                       } else if (isr & ISR_XDROP) {
+                               dev_err(&dev->dev,
+                                               "isr & ISR_ERR [%x] "
+                                               "ISR_XDROP \n", isr);
+                       } else {
+                               dev_err(&dev->dev,
+                                               "isr & ISR_ERR [%x]\n",
+                                               isr);
+                       }
+               }
+
+               if (isr & ISR_LEVENT) {
+                       adapter->linkevent_interrupts++;
+                       slic_link_event_handler(adapter);
+               }
+
+               if ((isr & ISR_UPC) || (isr & ISR_UPCERR) ||
+                   (isr & ISR_UPCBSY)) {
+                       adapter->upr_interrupts++;
+                       slic_upr_request_complete(adapter, isr);
+               }
+       }
+
+       if (isr & ISR_RCV) {
+               adapter->rcv_interrupts++;
+               slic_rcv_handler(adapter);
+       }
+
+       if (isr & ISR_CMD) {
+               adapter->xmit_interrupts++;
+               slic_xmit_complete(adapter);
+       }
+}
+
+
 static irqreturn_t slic_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = (struct net_device *)dev_id;
@@ -2641,64 +2694,7 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
                adapter->num_isrs++;
                switch (adapter->card->state) {
                case CARD_UP:
-                       if (isr & ~ISR_IO) {
-                               if (isr & ISR_ERR) {
-                                       adapter->error_interrupts++;
-                                       if (isr & ISR_RMISS) {
-                                               int count;
-                                               int pre_count;
-                                               int errors;
-
-                                               struct slic_rcvqueue *rcvq =
-                                                   &adapter->rcvqueue;
-
-                                               adapter->
-                                                   error_rmiss_interrupts++;
-                                               if (!rcvq->errors)
-                                                       rcv_count = rcvq->count;
-                                               pre_count = rcvq->count;
-                                               errors = rcvq->errors;
-
-                                               while (rcvq->count <
-                                                      SLIC_RCVQ_FILLTHRESH) {
-                                                       count =
-                                                           slic_rcvqueue_fill
-                                                           (adapter);
-                                                       if (!count)
-                                                               break;
-                                               }
-                                       } else if (isr & ISR_XDROP) {
-                                               dev_err(&dev->dev,
-                                                       "isr & ISR_ERR [%x] "
-                                                       "ISR_XDROP \n", isr);
-                                       } else {
-                                               dev_err(&dev->dev,
-                                                       "isr & ISR_ERR [%x]\n",
-                                                       isr);
-                                       }
-                               }
-
-                               if (isr & ISR_LEVENT) {
-                                       adapter->linkevent_interrupts++;
-                                       slic_link_event_handler(adapter);
-                               }
-
-                               if ((isr & ISR_UPC) ||
-                                   (isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
-                                       adapter->upr_interrupts++;
-                                       slic_upr_request_complete(adapter, isr);
-                               }
-                       }
-
-                       if (isr & ISR_RCV) {
-                               adapter->rcv_interrupts++;
-                               slic_rcv_handler(adapter);
-                       }
-
-                       if (isr & ISR_CMD) {
-                               adapter->xmit_interrupts++;
-                               slic_xmit_complete(adapter);
-                       }
+                       slic_interrupt_card_up(isr, adapter, dev);
                        break;
 
                case CARD_DOWN:
@@ -3645,16 +3641,15 @@ static int slic_entry_probe(struct pci_dev *pcidev,
                return err;
 
        if (slic_debug > 0 && did_version++ == 0) {
-               printk(KERN_DEBUG "%s\n", slic_banner);
-               printk(KERN_DEBUG "%s\n", slic_proc_version);
+               dev_dbg(&pcidev->dev, "%s\n", slic_banner);
+               dev_dbg(&pcidev->dev, "%s\n", slic_proc_version);
        }
 
        if (!pci_set_dma_mask(pcidev, DMA_BIT_MASK(64))) {
                pci_using_dac = 1;
                err = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64));
                if (err) {
-                       dev_err(&pcidev->dev, "unable to obtain 64-bit DMA for "
-                                       "consistent allocations\n");
+                       dev_err(&pcidev->dev, "unable to obtain 64-bit DMA for consistent allocations\n");
                        goto err_out_disable_pci;
                }
        } else {
@@ -3776,8 +3771,7 @@ static int __init slic_module_init(void)
        slic_init_driver();
 
        if (debug >= 0 && slic_debug != debug)
-               printk(KERN_DEBUG KBUILD_MODNAME ": debug level is %d.\n",
-                      debug);
+               pr_debug("debug level is %d.\n", debug);
        if (debug >= 0)
                slic_debug = debug;
 
index 8add64b1cb0940f69d783083588d65994c5c0e5c..ba199ffff1783cbf08a8892960f3a44c8bbd68cf 100644 (file)
@@ -130,7 +130,8 @@ static int __init sm7xx_vga_setup(char *options)
        for (i = 0; i < ARRAY_SIZE(vesa_mode_table); i++) {
                if (strstr(options, vesa_mode_table[i].index)) {
                        smtc_scr_info.lfb_width  = vesa_mode_table[i].lfb_width;
-                       smtc_scr_info.lfb_height = vesa_mode_table[i].lfb_height;
+                       smtc_scr_info.lfb_height =
+                                               vesa_mode_table[i].lfb_height;
                        smtc_scr_info.lfb_depth  = vesa_mode_table[i].lfb_depth;
                        return 0;
                }
@@ -259,8 +260,7 @@ static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
                        if (sfb->fb.var.bits_per_pixel == 16) {
                                u32 *pal = sfb->fb.pseudo_palette;
                                val = chan_to_field(red, &sfb->fb.var.red);
-                               val |= chan_to_field(green, \
-                                               &sfb->fb.var.green);
+                               val |= chan_to_field(green, &sfb->fb.var.green);
                                val |= chan_to_field(blue, &sfb->fb.var.blue);
 #ifdef __BIG_ENDIAN
                                pal[regno] =
@@ -274,8 +274,7 @@ static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
                        } else {
                                u32 *pal = sfb->fb.pseudo_palette;
                                val = chan_to_field(red, &sfb->fb.var.red);
-                               val |= chan_to_field(green, \
-                                               &sfb->fb.var.green);
+                               val |= chan_to_field(green, &sfb->fb.var.green);
                                val |= chan_to_field(blue, &sfb->fb.var.blue);
 #ifdef __BIG_ENDIAN
                                val =
@@ -508,9 +507,9 @@ static void sm7xx_set_timing(struct smtcfb_info *sfb)
 
                        /* init SEQ register SR30 - SR75 */
                        for (i = 0; i < SIZE_SR30_SR75; i++)
-                               if (((i + 0x30) != 0x62) \
-                                       && ((i + 0x30) != 0x6a) \
-                                       && ((i + 0x30) != 0x6b))
+                               if ((i + 0x30) != 0x62 &&
+                                   (i + 0x30) != 0x6a &&
+                                   (i + 0x30) != 0x6b)
                                        smtc_seqw(i + 0x30,
                                                VGAMode[j].Init_SR30_SR75[i]);
 
@@ -933,7 +932,6 @@ static void smtcfb_pci_remove(struct pci_dev *pdev)
        struct smtcfb_info *sfb;
 
        sfb = pci_get_drvdata(pdev);
-       pci_set_drvdata(pdev, NULL);
        smtc_unmap_smem(sfb);
        smtc_unmap_mmio(sfb);
        unregister_framebuffer(&sfb->fb);
index 8c3e7a60a9be380888cc6450353cbf0c9889880c..efd6f4560d3e55ceeab571fdc1d0ebc242a38df2 100644 (file)
@@ -51,6 +51,7 @@ config SPEAKUP_SYNTH_ACNTSA
 
 config SPEAKUP_SYNTH_ACNTPC
        tristate "Accent PC synthesizer support"
+       depends on ISA || COMPILE_TEST
        ---help---
                This is the Speakup driver for the accent pc
                synthesizer.  You can say y to build it into the kernel,
@@ -102,6 +103,7 @@ config SPEAKUP_SYNTH_DECEXT
 
 config SPEAKUP_SYNTH_DECPC
        depends on m
+       depends on ISA || COMPILE_TEST
        tristate "DECtalk PC (big ISA card) synthesizer support"
        ---help---
 
@@ -124,6 +126,7 @@ config SPEAKUP_SYNTH_DECPC
 
 config SPEAKUP_SYNTH_DTLK
        tristate "DoubleTalk PC synthesizer support"
+       depends on ISA || COMPILE_TEST
        ---help---
 
                This is the Speakup driver for the internal DoubleTalk
@@ -134,6 +137,7 @@ config SPEAKUP_SYNTH_DTLK
 
 config SPEAKUP_SYNTH_KEYPC
        tristate "Keynote Gold PC synthesizer support"
+       depends on ISA || COMPILE_TEST
        ---help---
 
                This is the Speakup driver for the Keynote Gold
index 51bdea3a5beada9a6de419abc9dad9b658355ad3..e2f597ee6261cb143e0f02ef05558734d24e2631 100644 (file)
@@ -585,6 +585,25 @@ ssize_t spk_var_show(struct kobject *kobj, struct kobj_attribute *attr,
 }
 EXPORT_SYMBOL_GPL(spk_var_show);
 
+/*
+ * Used to reset either default_pitch or default_vol.
+ */
+static inline void spk_reset_default_value(char *header_name,
+                                       int *synth_default_value, int idx)
+{
+       struct st_var_header *param;
+
+       if (synth && synth_default_value) {
+               param = spk_var_header_by_name(header_name);
+               if (param)  {
+                       spk_set_num_var(synth_default_value[idx],
+                                       param, E_NEW_DEFAULT);
+                       spk_set_num_var(0, param, E_DEFAULT);
+                       pr_info("%s reset to default value\n", param->name);
+               }
+       }
+}
+
 /*
  * This function is called when a user echos a value to one of the
  * variable parameters.
@@ -597,7 +616,7 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr,
        int len;
        char *cp;
        struct var_t *var_data;
-       int value;
+       long value;
        unsigned long flags;
 
        param = spk_var_header_by_name(attr->attr.name);
@@ -619,61 +638,54 @@ ssize_t spk_var_store(struct kobject *kobj, struct kobj_attribute *attr,
                        len = E_INC;
                else
                        len = E_SET;
-               value = simple_strtol(cp, NULL, 10);
-               ret = spk_set_num_var(value, param, len);
+               if (kstrtol(cp, 10, &value) == 0)
+                       ret = spk_set_num_var(value, param, len);
+               else
+                       pr_warn("overflow or parsing error has occured");
                if (ret == -ERANGE) {
                        var_data = param->data;
                        pr_warn("value for %s out of range, expect %d to %d\n",
-                               attr->attr.name,
+                               param->name,
                                var_data->u.n.low, var_data->u.n.high);
                }
+
+              /*
+               * If voice was just changed, we might need to reset our default
+               * pitch and volume.
+               */
+               if (param->var_id == VOICE && synth &&
+                   (ret == 0 || ret == -ERESTART)) {
+                       var_data = param->data;
+                       value = var_data->u.n.value;
+                       spk_reset_default_value("pitch", synth->default_pitch,
+                               value);
+                       spk_reset_default_value("vol", synth->default_vol,
+                               value);
+               }
                break;
        case VAR_STRING:
-               len = strlen(buf);
-               if ((len >= 1) && (buf[len - 1] == '\n'))
+               len = strlen(cp);
+               if ((len >= 1) && (cp[len - 1] == '\n'))
                        --len;
-               if ((len >= 2) && (buf[0] == '"') && (buf[len - 1] == '"')) {
-                       ++buf;
+               if ((len >= 2) && (cp[0] == '"') && (cp[len - 1] == '"')) {
+                       ++cp;
                        len -= 2;
                }
-               cp = (char *) buf;
                cp[len] = '\0';
-               ret = spk_set_string_var(buf, param, len);
+               ret = spk_set_string_var(cp, param, len);
                if (ret == -E2BIG)
                        pr_warn("value too long for %s\n",
-                                       attr->attr.name);
+                                       param->name);
                break;
        default:
                pr_warn("%s unknown type %d\n",
                        param->name, (int)param->var_type);
        break;
        }
-       /*
-        * If voice was just changed, we might need to reset our default
-        * pitch and volume.
-        */
-       if (strcmp(attr->attr.name, "voice") == 0) {
-               if (synth && synth->default_pitch) {
-                       param = spk_var_header_by_name("pitch");
-                       if (param)  {
-                               spk_set_num_var(synth->default_pitch[value],
-                                               param, E_NEW_DEFAULT);
-                               spk_set_num_var(0, param, E_DEFAULT);
-                       }
-               }
-               if (synth && synth->default_vol) {
-                       param = spk_var_header_by_name("vol");
-                       if (param)  {
-                               spk_set_num_var(synth->default_vol[value],
-                                               param, E_NEW_DEFAULT);
-                               spk_set_num_var(0, param, E_DEFAULT);
-                       }
-               }
-       }
        spin_unlock_irqrestore(&speakup_info.spinlock, flags);
 
        if (ret == -ERESTART)
-               pr_info("%s reset to default value\n", attr->attr.name);
+               pr_info("%s reset to default value\n", param->name);
        return count;
 }
 EXPORT_SYMBOL_GPL(spk_var_store);
index 14079c4949a8038e801474a2842f09e38e5bd403..47502fa5f3f60a50db71b21a90be9dc9ce9c54ba 100644 (file)
@@ -90,7 +90,7 @@ const struct st_bits_data spk_punc_info[] = {
        {"repeats", "()", CH_RPT},
        {"extended numeric", "", B_EXNUM},
        {"symbols", "", B_SYM},
-       {0, 0}
+       {NULL, NULL}
 };
 
 static char mark_cut_flag;
index 80141aca712f99039a7584d7b15f0201ce5c953c..1c8a7f4a0ef52035e8954197db31024815974811 100644 (file)
@@ -223,7 +223,7 @@ static void do_catch_up(struct spk_synth *synth)
                if (ch == '\n')
                        ch = PROCSPEECH;
                outb_p(ch, speakup_info.port_tts);
-               if (jiffies >= jiff_max && ch == SPACE) {
+               if (time_after_eq(jiffies, jiff_max) && ch == SPACE) {
                        timeout = SPK_XMITR_TIMEOUT;
                        while (synth_writable()) {
                                if (!--timeout)
index 95d3132f0a35717a2451070f140f2e237260f1bf..70cf1591676a2c2acb0f33bec628e83d719cbc30 100644 (file)
@@ -179,7 +179,7 @@ static void do_catch_up(struct spk_synth *synth)
                        schedule_timeout(msecs_to_jiffies(full_time_val));
                        continue;
                }
-               if ((jiffies >= jiff_max) && (ch == SPACE)) {
+               if (time_after_eq(jiffies, jiff_max) && (ch == SPACE)) {
                        spin_lock_irqsave(&speakup_info.spinlock, flags);
                        jiffy_delta_val = jiffy_delta->u.n.value;
                        full_time_val = full_time->u.n.value;
index 3508aee98ab0651e06b831c22d8e3dd80f975ce3..61a3ceeb0d3ae081258400749cfa68110d24e7a2 100644 (file)
@@ -39,7 +39,7 @@ static struct var_t vars[] = {
        { RATE, .u.n = {"\x05[r%d]", 10, 0, 20, 100, -10, NULL } },
        { PITCH, .u.n = {"\x05[f%d]", 80, 39, 4500, 0, 0, NULL } },
        { VOL, .u.n = {"\x05[g%d]", 21, 0, 40, 0, 0, NULL } },
-       { TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, 0 } },
+       { TONE, .u.n = {"\x05[s%d]", 9, 0, 63, 0, 0, NULL } },
        { PUNCT, .u.n = {"\x05[A%c]", 0, 0, 3, 0, 0, "nmsa" } },
        { DIRECT, .u.n = {NULL, 0, 0, 1, 0, 0, NULL } },
        V_LAST_VAR
index 9aa2a78cd71cd87dfad5785a9fab9d2f26e497e2..445a3fda380e7b456d49599be9703acadf227e3a 100644 (file)
@@ -46,7 +46,7 @@ static struct st_var_header var_headers[] = {
        { "direct", DIRECT, VAR_NUM, NULL, NULL },
 };
 
-static struct st_var_header *var_ptrs[MAXVARS] = { 0, 0, 0 };
+static struct st_var_header *var_ptrs[MAXVARS] = { NULL, NULL, NULL };
 
 static struct punc_var_t punc_vars[] = {
        { PUNC_SOME, 1 },
@@ -280,7 +280,7 @@ int spk_set_mask_bits(const char *input, const int which, const int how)
        if (!cp)
                cp = spk_punc_info[which].value;
        else {
-               for ( ; *cp; cp++) {
+               for (; *cp; cp++) {
                        if (*cp < SPACE)
                                break;
                        if (mask < PUNC) {
@@ -294,11 +294,11 @@ int spk_set_mask_bits(const char *input, const int which, const int how)
                cp = (u_char *)input;
        }
        if (how&2) {
-               for ( ; *cp; cp++)
+               for (; *cp; cp++)
                        if (*cp > SPACE)
                                spk_chartab[*cp] |= mask;
        } else {
-               for ( ; *cp; cp++)
+               for (; *cp; cp++)
                        if (*cp > SPACE)
                                spk_chartab[*cp] &= ~mask;
        }
index d460f5823c6b9a645c465db6d8cafe65223981de..012e4a38d2db70fd4d8df83eb7e770656335ce49 100644 (file)
@@ -36,7 +36,7 @@
 
 /*
  *  ======== dsp_init ========
- *     Allocates bridge resources. Loads a base image onto DSP, if specified.
+ *  Allocates bridge resources. Loads a base image onto DSP, if specified.
  */
 u32 dsp_init(u32 *init_status)
 {
@@ -106,7 +106,7 @@ func_cont:
 
 /*
  *  ======== dsp_deinit ========
- *     Frees the resources allocated for bridge.
+ *  Frees the resources allocated for bridge.
  */
 bool dsp_deinit(u32 device_context)
 {
index d8957a55662642ea248a6cbacbae23924f6122c4..76a1ff0e6275d9c50c1ff37191ef22e1fa38b81e 100644 (file)
@@ -357,8 +357,9 @@ static int stub_probe(struct usb_interface *interface,
        busid_priv = get_busid_priv(udev_busid);
        if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) ||
            (busid_priv->status == STUB_BUSID_OTHER)) {
-               dev_info(&interface->dev, "%s is not in match_busid table... "
-                        "skip!\n", udev_busid);
+               dev_info(&interface->dev,
+                       "%s is not in match_busid table... skip!\n",
+                       udev_busid);
 
                /*
                 * Return value should be ENODEV or ENOXIO to continue trying
@@ -375,8 +376,10 @@ static int stub_probe(struct usb_interface *interface,
        }
 
        if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
-               dev_dbg(&udev->dev, "%s is attached on vhci_hcd... skip!\n",
-                        udev_busid);
+               dev_dbg(&udev->dev,
+                       "%s is attached on vhci_hcd... skip!\n",
+                       udev_busid);
+
                return -ENODEV;
        }
 
@@ -386,10 +389,10 @@ static int stub_probe(struct usb_interface *interface,
                        return -ENODEV;
 
                busid_priv->interf_count++;
-               dev_info(&interface->dev, "usbip-host: register new interface "
-                        "(bus %u dev %u ifn %u)\n",
-                        udev->bus->busnum, udev->devnum,
-                        interface->cur_altsetting->desc.bInterfaceNumber);
+               dev_info(&interface->dev,
+                       "usbip-host: register new interface (bus %u dev %u ifn %u)\n",
+                       udev->bus->busnum, udev->devnum,
+                       interface->cur_altsetting->desc.bInterfaceNumber);
 
                /* set private data to usb_interface */
                usb_set_intfdata(interface, sdev);
@@ -412,9 +415,10 @@ static int stub_probe(struct usb_interface *interface,
        if (!sdev)
                return -ENOMEM;
 
-       dev_info(&interface->dev, "usbip-host: register new device "
-                "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum,
-                interface->cur_altsetting->desc.bInterfaceNumber);
+       dev_info(&interface->dev,
+               "usbip-host: register new device (bus %u dev %u ifn %u)\n",
+               udev->bus->busnum, udev->devnum,
+               interface->cur_altsetting->desc.bInterfaceNumber);
 
        busid_priv->interf_count = 0;
        busid_priv->shutdown_busid = 0;
index 33027cce6700506e6abaca6db07d5f8cf594a6cd..baf857f7cc88ac7873e8acaf790a9cb8de9b5aa3 100644 (file)
@@ -255,14 +255,14 @@ static int __init usbip_host_init(void)
        }
 
        ret = usb_register(&stub_driver);
-       if (ret < 0) {
+       if (ret) {
                pr_err("usb_register failed %d\n", ret);
                goto err_usb_register;
        }
 
        ret = driver_create_file(&stub_driver.drvwrap.driver,
                                 &driver_attr_match_busid);
-       if (ret < 0) {
+       if (ret) {
                pr_err("driver_create_file failed\n");
                goto err_create_file;
        }
index 2be4060f90363a693ffe635955ab462acef98eb8..0ee5d92639962ac65f13c1704e54bcb4dafb53de 100644 (file)
@@ -70,7 +70,6 @@ AC_ARG_WITH([tcp-wrappers],
                       [AC_MSG_RESULT([not found]); exit 1])
             else
                     AC_MSG_RESULT([no]);
-                    LIBS="$saved_LIBS"
             fi],
            dnl [ACTION-IF-NOT-GIVEN]
            [AC_MSG_RESULT([(default)])
index ccdadc87c47824fd56bd2a3a822c1909446961eb..a6097be25d28f6624ff373032e1fcc219490abc6 100644 (file)
@@ -3,7 +3,7 @@
 usbip \- manage USB/IP devices
 .SH SYNOPSIS
 .B usbip
-[\foptions\R] <\fIcommand\fR> <\fIargs\fR>
+[\fIoptions\fR] <\fIcommand\fR> <\fIargs\fR>
 
 .SH DESCRIPTION
 On a USB/IP server, devices can be listed, bound, and unbound using
@@ -23,6 +23,12 @@ Print debugging information.
 Log to syslog.
 .PP
 
+.HP
+\fB\-\-tcp-port PORT\fR
+.IP
+Connect to PORT on remote host (used for attach and list --remote).
+.PP
+
 .SH COMMANDS
 .HP
 \fBversion\fR
index d896936f1780765a7e4306462fc2b461e99e8a42..ac4635db3f0368ded92f66a4c1a815d58057c9e2 100644 (file)
@@ -14,9 +14,21 @@ Devices have to explicitly be exported using
 before usbipd makes them available to other hosts.
 
 The daemon accepts connections from USB/IP clients
-on TCP port 3240.
+on TCP port 3240 by default.
 
 .SH OPTIONS
+.HP
+\fB\-4\fR, \fB\-\-ipv4\fR
+.IP
+Bind to IPv4. Default is both.
+.PP
+
+.HP
+\fB\-6\fR, \fB\-\-ipv6\fR
+.IP
+Bind to IPv6. Default is both.
+.PP
+
 .HP
 \fB\-D\fR, \fB\-\-daemon\fR
 .IP
@@ -29,6 +41,19 @@ Run as a daemon process.
 Print debugging information.
 .PP
 
+.HP
+\fB\-PFILE\fR, \fB\-\-pid FILE\fR
+.IP
+Write process id to FILE.
+.br
+If no FILE specified, use /var/run/usbipd.pid
+.PP
+
+\fB\-tPORT\fR, \fB\-\-tcp\-port PORT\fR
+.IP
+Listen on TCP/IP port PORT.
+.PP
+
 \fB\-h\fR, \fB\-\-help\fR
 .IP
 Print the program help message and exit.
index c39a07f1d38cd0b122bebf572313d46c79d75cac..b4c37e76a6e08f7973bcf324dd87a612d621546d 100644 (file)
 #include <netinet/tcp.h>
 #include <unistd.h>
 
+#ifdef HAVE_LIBWRAP
+#include <tcpd.h>
+#endif
+
 #include "usbip_common.h"
 #include "usbip_network.h"
 
@@ -239,6 +243,18 @@ int usbip_net_set_keepalive(int sockfd)
        return ret;
 }
 
+int usbip_net_set_v6only(int sockfd)
+{
+       const int val = 1;
+       int ret;
+
+       ret = setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val));
+       if (ret < 0)
+               dbg("setsockopt: IPV6_V6ONLY");
+
+       return ret;
+}
+
 /*
  * IPv6 Ready
  */
index 2d0e4277b62be808fa9dc9d87d6339e223e58ea7..f19ae19799b4e13e9740fdcad6d01f0cf306c9bd 100644 (file)
@@ -180,6 +180,7 @@ int usbip_net_recv_op_common(int sockfd, uint16_t *code);
 int usbip_net_set_reuseaddr(int sockfd);
 int usbip_net_set_nodelay(int sockfd);
 int usbip_net_set_keepalive(int sockfd);
+int usbip_net_set_v6only(int sockfd);
 int usbip_net_tcp_connect(char *hostname, char *port);
 
 #endif /* __USBIP_NETWORK_H */
index 1c76cfd274d05e938bb2ce558b995ddeb61916b0..7980f8b5517b4b711f78691607a6970964c29def 100644 (file)
@@ -56,6 +56,13 @@ static const char usbip_version_string[] = PACKAGE_STRING;
 
 static const char usbipd_help_string[] =
        "usage: usbipd [options]\n"
+       "\n"
+       "       -4, --ipv4\n"
+       "               Bind to IPv4. Default is both.\n"
+       "\n"
+       "       -6, --ipv6\n"
+       "               Bind to IPv6. Default is both.\n"
+       "\n"
        "       -D, --daemon\n"
        "               Run as a daemon process.\n"
        "\n"
@@ -354,14 +361,15 @@ static void addrinfo_to_text(struct addrinfo *ai, char buf[],
        snprintf(buf, buf_size, "%s:%s", hbuf, sbuf);
 }
 
-static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[])
+static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[],
+                            int maxsockfd)
 {
        struct addrinfo *ai;
        int ret, nsockfd = 0;
        const size_t ai_buf_size = NI_MAXHOST + NI_MAXSERV + 2;
        char ai_buf[ai_buf_size];
 
-       for (ai = ai_head; ai && nsockfd < MAXSOCKFD; ai = ai->ai_next) {
+       for (ai = ai_head; ai && nsockfd < maxsockfd; ai = ai->ai_next) {
                int sock;
                addrinfo_to_text(ai, ai_buf, ai_buf_size);
                dbg("opening %s", ai_buf);
@@ -374,6 +382,9 @@ static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[])
 
                usbip_net_set_reuseaddr(sock);
                usbip_net_set_nodelay(sock);
+               /* We use seperate sockets for IPv4 and IPv6
+                * (see do_standalone_mode()) */
+               usbip_net_set_v6only(sock);
 
                if (sock >= FD_SETSIZE) {
                        err("FD_SETSIZE: %s: sock=%d, max=%d",
@@ -402,11 +413,6 @@ static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[])
                sockfdlist[nsockfd++] = sock;
        }
 
-       if (nsockfd == 0)
-               return -1;
-
-       dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es");
-
        return nsockfd;
 }
 
@@ -473,11 +479,11 @@ static void remove_pid_file()
        }
 }
 
-static int do_standalone_mode(int daemonize)
+static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
 {
        struct addrinfo *ai_head;
        int sockfdlist[MAXSOCKFD];
-       int nsockfd;
+       int nsockfd, family;
        int i, terminate;
        struct pollfd *fds;
        struct timespec timeout;
@@ -501,21 +507,36 @@ static int do_standalone_mode(int daemonize)
        set_signal();
        write_pid_file();
 
-       ai_head = do_getaddrinfo(NULL, PF_UNSPEC);
+       info("starting " PROGNAME " (%s)", usbip_version_string);
+
+       /*
+        * To suppress warnings on systems with bindv6only disabled
+        * (default), we use seperate sockets for IPv6 and IPv4 and set
+        * IPV6_V6ONLY on the IPv6 sockets.
+        */
+       if (ipv4 && ipv6)
+               family = AF_UNSPEC;
+       else if (ipv4)
+               family = AF_INET;
+       else
+               family = AF_INET6;
+
+       ai_head = do_getaddrinfo(NULL, family);
        if (!ai_head) {
                usbip_host_driver_close();
                return -1;
        }
-
-       info("starting " PROGNAME " (%s)", usbip_version_string);
-
-       nsockfd = listen_all_addrinfo(ai_head, sockfdlist);
+       nsockfd = listen_all_addrinfo(ai_head, sockfdlist,
+               sizeof(sockfdlist) / sizeof(*sockfdlist));
+       freeaddrinfo(ai_head);
        if (nsockfd <= 0) {
                err("failed to open a listening socket");
-               freeaddrinfo(ai_head);
                usbip_host_driver_close();
                return -1;
        }
+
+       dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es");
+
        fds = calloc(nsockfd, sizeof(struct pollfd));
        for (i = 0; i < nsockfd; i++) {
                fds[i].fd = sockfdlist[i];
@@ -551,7 +572,6 @@ static int do_standalone_mode(int daemonize)
 
        info("shutting down " PROGNAME);
        free(fds);
-       freeaddrinfo(ai_head);
        usbip_host_driver_close();
 
        return 0;
@@ -560,6 +580,9 @@ static int do_standalone_mode(int daemonize)
 int main(int argc, char *argv[])
 {
        static const struct option longopts[] = {
+               { "ipv4",     no_argument,       NULL, '4' },
+               { "ipv6",     no_argument,       NULL, '6' },
+               { "daemon",   no_argument,       NULL, 'D' },
                { "daemon",   no_argument,       NULL, 'D' },
                { "debug",    no_argument,       NULL, 'd' },
                { "pid",      optional_argument, NULL, 'P' },
@@ -576,6 +599,7 @@ int main(int argc, char *argv[])
        } cmd;
 
        int daemonize = 0;
+       int ipv4 = 0, ipv6 = 0;
        int opt, rc = -1;
        pid_file = NULL;
 
@@ -587,12 +611,18 @@ int main(int argc, char *argv[])
 
        cmd = cmd_standalone_mode;
        for (;;) {
-               opt = getopt_long(argc, argv, "DdP::t:hv", longopts, NULL);
+               opt = getopt_long(argc, argv, "46DdP::t:hv", longopts, NULL);
 
                if (opt == -1)
                        break;
 
                switch (opt) {
+               case '4':
+                       ipv4 = 1;
+                       break;
+               case '6':
+                       ipv6 = 1;
+                       break;
                case 'D':
                        daemonize = 1;
                        break;
@@ -618,9 +648,12 @@ int main(int argc, char *argv[])
                }
        }
 
+       if (!ipv4 && !ipv6)
+               ipv4 = ipv6 = 1;
+
        switch (cmd) {
        case cmd_standalone_mode:
-               rc = do_standalone_mode(daemonize);
+               rc = do_standalone_mode(daemonize, ipv4, ipv6);
                remove_pid_file();
                break;
        case cmd_version:
index d7974cb2cc6f7f499cac46297e41e8f43240f8af..e810ad53e2acfe519a448eedc84830fcc547afae 100644 (file)
@@ -999,12 +999,6 @@ static int vhci_hcd_probe(struct platform_device *pdev)
 
        usbip_dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
 
-       /* will be removed */
-       if (pdev->dev.dma_mask) {
-               dev_info(&pdev->dev, "vhci_hcd DMA not supported\n");
-               return -EINVAL;
-       }
-
        /*
         * Allocate and initialize hcd.
         * Our private data is also allocated automatically.
@@ -1146,11 +1140,11 @@ static int __init vhci_hcd_init(void)
                return -ENODEV;
 
        ret = platform_driver_register(&vhci_driver);
-       if (ret < 0)
+       if (ret)
                goto err_driver_register;
 
        ret = platform_device_register(&the_pdev);
-       if (ret < 0)
+       if (ret)
                goto err_platform_device_register;
 
        pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
index 76c8490b0734d212297e8fb00583c73bbaa5716b..7949d58ad7d153e8508556db9f4ef10f349e1c38 100644 (file)
@@ -165,9 +165,8 @@ vMgrDecodeBeacon(
                        break;
 
                case WLAN_EID_RSN:
-                       if (pFrame->pRSN == NULL) {
+                       if (pFrame->pRSN == NULL)
                                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                       }
                        break;
                case WLAN_EID_RSN_WPA:
                        if (pFrame->pRSNWPA == NULL) {
@@ -382,9 +381,8 @@ vMgrDecodeAssocRequest(
                        break;
 
                case WLAN_EID_RSN:
-                       if (pFrame->pRSN == NULL) {
+                       if (pFrame->pRSN == NULL)
                                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                       }
                        break;
                case WLAN_EID_RSN_WPA:
                        if (pFrame->pRSNWPA == NULL) {
@@ -556,9 +554,8 @@ vMgrDecodeReassocRequest(
                        break;
 
                case WLAN_EID_RSN:
-                       if (pFrame->pRSN == NULL) {
+                       if (pFrame->pRSN == NULL)
                                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                       }
                        break;
                case WLAN_EID_RSN_WPA:
                        if (pFrame->pRSNWPA == NULL) {
@@ -742,9 +739,8 @@ vMgrDecodeProbeResponse(
                        break;
 
                case WLAN_EID_RSN:
-                       if (pFrame->pRSN == NULL) {
+                       if (pFrame->pRSN == NULL)
                                pFrame->pRSN = (PWLAN_IE_RSN)pItem;
-                       }
                        break;
                case WLAN_EID_RSN_WPA:
                        if (pFrame->pRSNWPA == NULL) {
@@ -858,9 +854,9 @@ vMgrDecodeAuthen(
        pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
                           + WLAN_AUTHEN_OFF_CHALLENGE);
 
-       if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) {
+       if (((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len) &&
+           pItem->byElementID == WLAN_EID_CHALLENGE)
                pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem;
-       }
 
        return;
 }
index fc056fc6199516cfe7d7f63fdecd5548e9f2e72f..82b0bd1c056a0e9e3cc4e98f600b6242b4769231 100644 (file)
@@ -46,7 +46,7 @@
  * SBOX Table
  */
 
-unsigned char sbox_table[256] =
+static unsigned char sbox_table[256] =
 {
        0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
        0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
@@ -66,7 +66,7 @@ unsigned char sbox_table[256] =
        0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
 };
 
-unsigned char dot2_table[256] = {
+static unsigned char dot2_table[256] = {
        0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
        0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
        0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
@@ -85,7 +85,7 @@ unsigned char dot2_table[256] = {
        0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
 };
 
-unsigned char dot3_table[256] = {
+static unsigned char dot3_table[256] = {
        0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
        0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
        0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
@@ -110,7 +110,7 @@ unsigned char dot3_table[256] = {
 
 /*---------------------  Export Functions  --------------------------*/
 
-void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
+static void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
 {
        unsigned long *dwPtrA = (unsigned long *)a;
        unsigned long *dwPtrB = (unsigned long *)b;
@@ -122,7 +122,7 @@ void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
        (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
 }
 
-void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
+static void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
 {
        unsigned long *dwPtrA = (unsigned long *)a;
        unsigned long *dwPtrB = (unsigned long *)b;
@@ -131,7 +131,7 @@ void xor_32(unsigned char *a, unsigned char *b, unsigned char *out)
        (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
 }
 
-void AddRoundKey(unsigned char *key, int round)
+static void AddRoundKey(unsigned char *key, int round)
 {
        unsigned char sbox_key[4];
        unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
@@ -149,7 +149,7 @@ void AddRoundKey(unsigned char *key, int round)
        xor_32(&key[12], &key[8], &key[12]);
 }
 
-void SubBytes(unsigned char *in, unsigned char *out)
+static void SubBytes(unsigned char *in, unsigned char *out)
 {
        int i;
 
@@ -158,7 +158,7 @@ void SubBytes(unsigned char *in, unsigned char *out)
        }
 }
 
-void ShiftRows(unsigned char *in, unsigned char *out)
+static void ShiftRows(unsigned char *in, unsigned char *out)
 {
        out[0]  = in[0];
        out[1]  = in[5];
@@ -178,7 +178,7 @@ void ShiftRows(unsigned char *in, unsigned char *out)
        out[15] = in[11];
 }
 
-void MixColumns(unsigned char *in, unsigned char *out)
+static void MixColumns(unsigned char *in, unsigned char *out)
 {
        out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
        out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3];
@@ -186,7 +186,7 @@ void MixColumns(unsigned char *in, unsigned char *out)
        out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
 }
 
-void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
+static void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
 {
        int  i;
        int  round;
index f983915168b7883c30a435c4561b8571abb77f75..a23b591eeac3d7432a73e78990342ef0ce65c15d 100644 (file)
@@ -148,7 +148,8 @@ BSSpSearchBSSList(
                        if (pDevice->bLinkPass == false) pCurrBSS->bSelected = false;
                        if ((pCurrBSS->bActive) &&
                            (pCurrBSS->bSelected == false)) {
-                               if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) {
+                               if (ether_addr_equal(pCurrBSS->abyBSSID,
+                                                    pbyBSSID)) {
                                        if (pSSID != NULL) {
                                                // compare ssid
                                                if (!memcmp(pSSID->abySSID,
@@ -275,7 +276,8 @@ BSSvClearBSSList(
        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                if (bKeepCurrBSSID) {
                        if (pMgmt->sBSSList[ii].bActive &&
-                           !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) {
+                           ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                            pMgmt->abyCurrBSSID)) {
                                // bKeepCurrBSSID = false;
                                continue;
                        }
@@ -318,7 +320,7 @@ BSSpAddrIsInBSSList(
        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                pBSSList = &(pMgmt->sBSSList[ii]);
                if (pBSSList->bActive) {
-                       if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) {
+                       if (ether_addr_equal(pBSSList->abyBSSID, abyBSSID)) {
                                if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len) {
                                        if (memcmp(pSSID->abySSID,
                                                   ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
@@ -733,7 +735,8 @@ BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr,
        // Index = 0 reserved for AP Node
        for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
                if (pMgmt->sNodeDBTable[ii].bActive) {
-                       if (!compare_ether_addr(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) {
+                       if (ether_addr_equal(abyDstAddr,
+                                            pMgmt->sNodeDBTable[ii].abyMACAddr)) {
                                *puNodeIndex = ii;
                                return true;
                        }
index 7f36a7103c3ef3812c20963d9f6ab6a51757069b..e93fdc88d84456ed52a8cb6cdaf9c02289c695c2 100644 (file)
@@ -1153,10 +1153,6 @@ static void device_free_info(PSDevice pDevice) {
                pci_release_regions(pDevice->pcid);
        if (dev)
                free_netdev(dev);
-
-       if (pDevice->pcid) {
-               pci_set_drvdata(pDevice->pcid, NULL);
-       }
 }
 
 static bool device_init_rings(PSDevice pDevice) {
index a9533f3f25299cc77e9158712d218347dada3cb3..0ff51cb4a207eeb045720a3884be0eebefc11823 100644 (file)
@@ -172,9 +172,9 @@ s_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr,
        };
 
        pbyRxBuffer = (unsigned char *)(pbyRxBufferAddr + cbHeaderSize);
-       if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
+       if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) {
                cbHeaderSize += 6;
-       } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
+       } else if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_RFC1042)) {
                cbHeaderSize += 6;
                pwType = (unsigned short *)(pbyRxBufferAddr + cbHeaderSize);
                if ((*pwType != TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) {
@@ -420,7 +420,8 @@ device_receive_frame(
        s_vGetDASA(skb->data+4, &cbHeaderSize, &pDevice->sRxEthHeader);
 
        // filter packet send from myself
-       if (!compare_ether_addr((unsigned char *)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr))
+       if (ether_addr_equal(pDevice->sRxEthHeader.abySrcAddr,
+                            pDevice->abyCurrentNetAddr))
                return false;
 
        if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
index 8acff44a9e753f38481a8b74c6c20a3b62d7f452..aab0012bba92909611659b78ef982d48aec82cfb 100644 (file)
@@ -720,7 +720,6 @@ static int hostap_get_encryption(PSDevice pDevice,
  * Return Value:
  *
  */
-
 int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
 {
        struct viawget_hostapd_param *param;
@@ -731,7 +730,7 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
            p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
                return -EINVAL;
 
-       param = kmalloc((int)p->length, (int)GFP_KERNEL);
+       param = kmalloc((int)p->length, GFP_KERNEL);
        if (param == NULL)
                return -ENOMEM;
 
@@ -755,8 +754,8 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
                break;
        case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
-               return -EOPNOTSUPP;
-               break;
+               ret = -EOPNOTSUPP;
+               goto out;
        case VIAWGET_HOSTAPD_FLUSH:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
                spin_lock_irq(&pDevice->lock);
@@ -790,40 +789,36 @@ int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p)
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
                ret = hostap_set_flags_sta(pDevice, param);
                break;
-
        case VIAWGET_HOSTAPD_MLME:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
-               return -EOPNOTSUPP;
-
+               ret = -EOPNOTSUPP;
+               goto out;
        case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
                ret = hostap_set_generic_element(pDevice, param);
                break;
-
        case VIAWGET_HOSTAPD_SCAN_REQ:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
-               return -EOPNOTSUPP;
-
+               ret = -EOPNOTSUPP;
+               goto out;
        case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
-               return -EOPNOTSUPP;
-
+               ret = -EOPNOTSUPP;
+               goto out;
        default:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6655_hostap_ioctl: unknown cmd=%d\n",
                        (int)param->cmd);
-               return -EOPNOTSUPP;
-               break;
+               ret = -EOPNOTSUPP;
+               goto out;
        }
 
        if ((ret == 0) && ap_ioctl) {
                if (copy_to_user(p->pointer, param, p->length)) {
                        ret = -EFAULT;
-                       goto out;
                }
        }
 
 out:
        kfree(param);
-
        return ret;
 }
index 9de698ef25f5de0511b2f3ebc98c197c4f6566f8..4bff8aa96be71689c707f858f4aed6f20d1acb17 100644 (file)
@@ -663,7 +663,8 @@ int iwctl_siwap(struct net_device *dev,
                        unsigned int ii, uSameBssidNum = 0;
                        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                                if (pMgmt->sBSSList[ii].bActive &&
-                                   !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyDesireBSSID)) {
+                                   ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                                    pMgmt->abyDesireBSSID)) {
                                        uSameBssidNum++;
                                }
                        }
@@ -840,7 +841,8 @@ int iwctl_siwessid(struct net_device *dev,
                                        //         by means of judging if there are two same BSSID exist in list ?
                                        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                                                if (pMgmt->sBSSList[ii].bActive &&
-                                                   !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
+                                                   ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                                                    pCurr->abyBSSID)) {
                                                        uSameBssidNum++;
                                                }
                                        }
index 92b84b5ea115cd0ee465e097078bbd4bd9866500..04c1304d16e59105b9616029bc6da2a2db0f8abc 100644 (file)
@@ -141,7 +141,7 @@ bool KeybGetKey(
        *pKey = NULL;
        for (i = 0; i < MAX_KEY_TABLE; i++) {
                if ((pTable->KeyTable[i].bInUse == true) &&
-                   !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                   ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        if (dwKeyIndex == 0xFFFFFFFF) {
                                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
                                        *pKey = &(pTable->KeyTable[i].PairwiseKey);
@@ -208,7 +208,7 @@ bool KeybSetKey(
                        j = i;
                }
                if ((pTable->KeyTable[i].bInUse == true) &&
-                   !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                   ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        // found table already exist
                        if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                                // Pairwise key
@@ -385,7 +385,7 @@ bool KeybRemoveKey(
 
        for (i = 0; i < MAX_KEY_TABLE; i++) {
                if ((pTable->KeyTable[i].bInUse == true) &&
-                   !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                   ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                                pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
                                s_vCheckKeyTableValid(pTable, dwIoBase);
@@ -429,7 +429,7 @@ bool KeybRemoveAllKey(
 
        for (i = 0; i < MAX_KEY_TABLE; i++) {
                if ((pTable->KeyTable[i].bInUse == true) &&
-                   !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                   ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
                        for (u = 0; u < MAX_GROUP_KEY; u++) {
                                pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
@@ -512,7 +512,7 @@ bool KeybGetTransmitKey(
        *pKey = NULL;
        for (i = 0; i < MAX_KEY_TABLE; i++) {
                if ((pTable->KeyTable[i].bInUse == true) &&
-                   !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                   ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
                        if (dwKeyType == PAIRWISE_KEY) {
                                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
                                        *pKey = &(pTable->KeyTable[i].PairwiseKey);
index 0828d18ad528ae9ec6ba74f125b7e126052fc4fb..387d20623aa3972d26c3ba1ec0eca2c466b378cd 100644 (file)
@@ -39,18 +39,18 @@ void MIC_vInit(unsigned long dwK0, unsigned long dwK1);
 
 void MIC_vUnInit(void);
 
-// Append bytes to the message to be MICed
+/* Append bytes to the message to be MICed */
 void MIC_vAppend(unsigned char *src, unsigned int nBytes);
 
-// Get the MIC result. Destination should accept 8 bytes of result.
-// This also resets the message to empty.
+/* Get the MIC result. Destination should accept 8 bytes of result. */
+/* This also resets the message to empty. */
 void MIC_vGetMIC(unsigned long *pdwL, unsigned long *pdwR);
 
 /*---------------------  Export Macros ------------------------------*/
 
-// Rotation functions on 32 bit values
+/* Rotation functions on 32 bit values */
 #define ROL32(A, n)                                                    \
        (((A) << (n)) | (((A)>>(32-(n)))  & ((1UL << (n)) - 1)))
 #define ROR32(A, n) ROL32((A), 32-(n))
 
-#endif //__MICHAEL_H__
+#endif /*__MICHAEL_H__ */
index 6948984a25ab0b6295449e5c6b56503179faa240..ce173cc16c192544da18dc3d0dddf09be1ed553a 100644 (file)
@@ -55,7 +55,7 @@
 
 /*---------------------  Static Variables  --------------------------*/
 
-const unsigned long dwAL2230InitTable[CB_AL2230_INIT_SEQ] = {
+static const unsigned long dwAL2230InitTable[CB_AL2230_INIT_SEQ] = {
        0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
        0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
        0x01A00200+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, //
@@ -73,7 +73,7 @@ const unsigned long dwAL2230InitTable[CB_AL2230_INIT_SEQ] = {
        0x00580F00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW
 };
 
-const unsigned long dwAL2230ChannelTable0[CB_MAX_CHANNEL] = {
+static const unsigned long dwAL2230ChannelTable0[CB_MAX_CHANNEL] = {
        0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
        0x03F79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
        0x03E79000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
@@ -90,7 +90,7 @@ const unsigned long dwAL2230ChannelTable0[CB_MAX_CHANNEL] = {
        0x03E7C000+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 14, Tf = 2412M
 };
 
-const unsigned long dwAL2230ChannelTable1[CB_MAX_CHANNEL] = {
+static const unsigned long dwAL2230ChannelTable1[CB_MAX_CHANNEL] = {
        0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
        0x0B333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
        0x03333100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
@@ -107,7 +107,7 @@ const unsigned long dwAL2230ChannelTable1[CB_MAX_CHANNEL] = {
        0x06666100+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 14, Tf = 2412M
 };
 
-unsigned long dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
+static unsigned long dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
        0x04040900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
        0x04041900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
        0x04042900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
@@ -177,7 +177,7 @@ unsigned long dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
 //{{ RobertYu:20050104
 // 40MHz reference frequency
 // Need to Pull PLLON(PE3) low when writing channel registers through 3-wire.
-const unsigned long dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
+static const unsigned long dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
        0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a
        0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel1 // Need modify for 11a
        0x841FF200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 451FE2
@@ -200,7 +200,7 @@ const unsigned long dwAL7230InitTable[CB_AL7230_INIT_SEQ] = {
        0x1ABA8F00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // Need modify for 11a: 12BACF
 };
 
-const unsigned long dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = {
+static const unsigned long dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = {
        0x0FF52000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g
        0x00000100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Channel184 // Need modify for 11b/g
        0x451FE200+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11b/g
@@ -219,7 +219,7 @@ const unsigned long dwAL7230InitTableAMode[CB_AL7230_INIT_SEQ] = {
        0x12BACF00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // Need modify for 11b/g
 };
 
-const unsigned long dwAL7230ChannelTable0[CB_MAX_CHANNEL] = {
+static const unsigned long dwAL7230ChannelTable0[CB_MAX_CHANNEL] = {
        0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
        0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
        0x00379000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
@@ -285,7 +285,7 @@ const unsigned long dwAL7230ChannelTable0[CB_MAX_CHANNEL] = {
        0x0FF61000+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 165, Tf = 5825MHz (56)
 };
 
-const unsigned long dwAL7230ChannelTable1[CB_MAX_CHANNEL] = {
+static const unsigned long dwAL7230ChannelTable1[CB_MAX_CHANNEL] = {
        0x13333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
        0x1B333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
        0x03333100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
@@ -349,7 +349,7 @@ const unsigned long dwAL7230ChannelTable1[CB_MAX_CHANNEL] = {
        0x02AAA100+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW  // channel = 165, Tf = 5825MHz (56)
 };
 
-const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
+static const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
        0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  1, Tf = 2412MHz
        0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  2, Tf = 2417MHz
        0x7FD78400+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // channel =  3, Tf = 2422MHz
@@ -428,7 +428,7 @@ const unsigned long dwAL7230ChannelTable2[CB_MAX_CHANNEL] = {
  * Return Value: true if succeeded; false if failed.
  *
  */
-bool s_bAL7230Init(unsigned long dwIoBase)
+static bool s_bAL7230Init(unsigned long dwIoBase)
 {
        int     ii;
        bool bResult;
@@ -471,7 +471,7 @@ bool s_bAL7230Init(unsigned long dwIoBase)
 }
 
 // Need to Pull PLLON low when writing channel registers through 3-wire interface
-bool s_bAL7230SelectChannel(unsigned long dwIoBase, unsigned char byChannel)
+static bool s_bAL7230SelectChannel(unsigned long dwIoBase, unsigned char byChannel)
 {
        bool bResult;
 
@@ -631,7 +631,7 @@ bool IFRFbWriteEmbedded(unsigned long dwIoBase, unsigned long dwData)
  * Return Value: true if succeeded; false if failed.
  *
  */
-bool RFbAL2230Init(unsigned long dwIoBase)
+static bool RFbAL2230Init(unsigned long dwIoBase)
 {
        int     ii;
        bool bResult;
@@ -678,7 +678,7 @@ bool RFbAL2230Init(unsigned long dwIoBase)
        return bResult;
 }
 
-bool RFbAL2230SelectChannel(unsigned long dwIoBase, unsigned char byChannel)
+static bool RFbAL2230SelectChannel(unsigned long dwIoBase, unsigned char byChannel)
 {
        bool bResult;
 
@@ -775,36 +775,6 @@ bool RFbInit(
        return bResult;
 }
 
-/*
- * Description: RF ShutDown function
- *
- * Parameters:
- *  In:
- *      byBBType
- *      byRFType
- *  Out:
- *      none
- *
- * Return Value: true if succeeded; false if failed.
- *
- */
-bool RFbShutDown(
-       PSDevice  pDevice
-)
-{
-       bool bResult = true;
-
-       switch (pDevice->byRFType) {
-       case RF_AIROHA7230:
-               bResult = IFRFbWriteEmbedded(pDevice->PortOffset, 0x1ABAEF00 + (BY_AL7230_REG_LEN << 3) + IFREGCTL_REGW);
-               break;
-       default:
-               bResult = true;
-               break;
-       }
-       return bResult;
-}
-
 /*
  * Description: Select channel
  *
index d8f4f8e7d05eba72281375483ca35fe09f7fbd46..d2bdb71fe62d37a914e5d9fc0c43fff570425320 100644 (file)
@@ -752,25 +752,3 @@ VNTWIFIbChannelSwitch(
        //spin_unlock_irq(&pDevice->lock);
        return true;
 }
-
-/*
-  bool
-  VNTWIFIbRadarPresent(
-  void *pMgmtObject,
-  unsigned char byChannel
-) {
-  PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
-  if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
-  (byChannel == (unsigned char) pMgmt->uCurrChannel) &&
-  (pMgmt->bSwitchChannel != true) &&
-  (pMgmt->b11hEnable == true)) {
-  if (!compare_ether_addr(pMgmt->abyIBSSDFSOwner, CARDpGetCurrentAddress(pMgmt->pAdapter))) {
-  pMgmt->byNewChannel = CARDbyAutoChannelSelect(pMgmt->pAdapter,(unsigned char) pMgmt->uCurrChannel);
-  pMgmt->bSwitchChannel = true;
-  }
-  BEACONbSendBeacon(pMgmt);
-  CARDbChannelSwitch(pMgmt->pAdapter, 0, pMgmt->byNewChannel, 10);
-  }
-  return true;
-  }
-*/
index d551653537b4a305c4045b65feadd5714ad84237..9c57eefe78fb12c9109a6aa2930046f3cf03c41b 100644 (file)
@@ -233,7 +233,7 @@ s_vProbeChannel(
  *
  *
  * Return Value:
- *    A ptr to Tx frame or NULL on allocation failue
+ *    A ptr to Tx frame or NULL on allocation failure
  *
  -*/
 
index 9eb81b4eee806b3ccda7331c4a0245182a22ec4d..f05f9f55398bf7a390068495b60ace381a978bc7 100644 (file)
@@ -75,8 +75,8 @@ bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader)
                for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) {
                        pCacheEntry = &(pCache->asCacheEntry[uIndex]);
                        if ((pCacheEntry->wFmSequence == pMACHeader->wSeqCtl) &&
-                           (!compare_ether_addr(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
-) {
+                           ether_addr_equal(pCacheEntry->abyAddr2,
+                                            pMACHeader->abyAddr2)) {
                                /* Duplicate match */
                                return true;
                        }
@@ -111,8 +111,8 @@ unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader)
 
        for (ii = 0; ii < pDevice->cbDFCB; ii++) {
                if ((pDevice->sRxDFCB[ii].bInUse == true) &&
-                   (!compare_ether_addr(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
-) {
+                   ether_addr_equal(pDevice->sRxDFCB[ii].abyAddr2,
+                                    pMACHeader->abyAddr2)) {
                        //
                        return ii;
                }
index 9938813f997a276227d1cdaae10fc245e97f886b..ed4b32b6d9cee7c4fdf8e1ca6c33ea61b06f928c 100644 (file)
@@ -1680,7 +1680,8 @@ s_vMgrRxDeauthentication(
                        vMgrDecodeDeauthen(&sFrame);
                        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
                        // TODO: update BSS list for specific BSSID if pre-authentication case
-                       if (!compare_ether_addr(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) {
+                       if (ether_addr_equal(sFrame.pHdr->sA3.abyAddr3,
+                                            pMgmt->abyCurrBSSID)) {
                                if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
                                        pMgmt->sNodeDBTable[0].bActive = false;
                                        pMgmt->eCurrMode = WMAC_MODE_STANDBY;
index e8d9ecd2913aa32d512e94ddc3ef0fb522904fa2..044368a46c53f332d45f9387722563143139c468 100644 (file)
@@ -394,7 +394,7 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel)
 
                } else {
                        // Key Table Full
-                       if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
+                       if (ether_addr_equal(param->addr, pDevice->abyBSSID)) {
                                //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
                                //spin_unlock_irq(&pDevice->lock);
                                return -EINVAL;
index b61328fbee87d41b68789e909c85d360e27577a7..85302c5e2bac41ff6e93ecc439dd4efd78eb7bf5 100644 (file)
@@ -179,7 +179,7 @@ bool ROUTEbRelay(PSDevice pDevice, unsigned char *pbySkbData, unsigned int uData
                pHeadTD = pHeadTD->next;
        }
 
-       pLastTD->pTDInfo->skb = 0;
+       pLastTD->pTDInfo->skb = NULL;
        pLastTD->pTDInfo->byFlags = 0;
 
        pDevice->apCurrTD[TYPE_AC0DMA] = pHeadTD;
index 5ecc190ae775581e41224cedcfc48fa5876b3b4e..3abc1d36f89dedab58e9e8840c30722b7ae979f7 100644 (file)
@@ -41,4 +41,4 @@
 
 bool ROUTEbRelay(PSDevice pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex);
 
-#endif // __WROUTE_H__
+#endif /* __WROUTE_H__ */
index ee79bbdf1a06ad0e48c23a24ba48f40be1d2778e..dad3f8c78e21d196540c62741af4fbbbe305819b 100644 (file)
@@ -57,6 +57,7 @@
 #include "control.h"
 #include "rndis.h"
 #include "iowpa.h"
+#include "power.h"
 
 static int          msglevel                =MSG_LEVEL_INFO;
 //static int          msglevel                =MSG_LEVEL_DEBUG;
@@ -126,7 +127,7 @@ PKnownBSS BSSpSearchBSSList(struct vnt_private *pDevice,
 
             if ((pCurrBSS->bActive) &&
                 (pCurrBSS->bSelected == false)) {
-                   if (!compare_ether_addr(pCurrBSS->abyBSSID, pbyBSSID)) {
+                   if (ether_addr_equal(pCurrBSS->abyBSSID, pbyBSSID)) {
                     if (pSSID != NULL) {
                         // compare ssid
                         if ( !memcmp(pSSID->abySSID,
@@ -242,8 +243,8 @@ void BSSvClearBSSList(struct vnt_private *pDevice, int bKeepCurrBSSID)
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
         if (bKeepCurrBSSID) {
             if (pMgmt->sBSSList[ii].bActive &&
-               !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
-                                   pMgmt->abyCurrBSSID)) {
+               ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                pMgmt->abyCurrBSSID)) {
  //mike mark: there are two BSSID's in list. If that AP is in hidden ssid mode, one SSID is null,
  //                 but other's might not be obvious, so if it associate's with your STA,
  //                 you must keep the two of them!!
@@ -277,7 +278,7 @@ PKnownBSS BSSpAddrIsInBSSList(struct vnt_private *pDevice,
     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
         pBSSList = &(pMgmt->sBSSList[ii]);
         if (pBSSList->bActive) {
-               if (!compare_ether_addr(pBSSList->abyBSSID, abyBSSID)) {
+               if (ether_addr_equal(pBSSList->abyBSSID, abyBSSID)) {
                 if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len){
                     if (memcmp(pSSID->abySSID,
                             ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
@@ -623,8 +624,8 @@ int BSSbIsSTAInNodeDB(struct vnt_private *pDevice,
     // Index = 0 reserved for AP Node
     for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
         if (pMgmt->sNodeDBTable[ii].bActive) {
-               if (!compare_ether_addr(abyDstAddr,
-                                       pMgmt->sNodeDBTable[ii].abyMACAddr)) {
+               if (ether_addr_equal(abyDstAddr,
+                                    pMgmt->sNodeDBTable[ii].abyMACAddr)) {
                 *puNodeIndex = ii;
                 return true;
             }
@@ -813,8 +814,10 @@ void BSSvAddMulticastNode(struct vnt_private *pDevice)
  *
 -*/
 
-void BSSvSecondCallBack(struct vnt_private *pDevice)
+void BSSvSecondCallBack(struct work_struct *work)
 {
+       struct vnt_private *pDevice = container_of(work,
+                       struct vnt_private, second_callback_work.work);
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        int ii;
        PWLAN_IE_SSID pItemSSID, pCurrSSID;
@@ -822,6 +825,9 @@ void BSSvSecondCallBack(struct vnt_private *pDevice)
        u32 uNonShortSlotSTACnt = 0;
        u32 uLongPreambleSTACnt = 0;
 
+       if (pDevice->Flags & fMP_DISCONNECTED)
+               return;
+
     spin_lock_irq(&pDevice->lock);
 
     pDevice->uAssocCount = 0;
@@ -1119,15 +1125,26 @@ else {
         }
     }
 
-    if (pDevice->bLinkPass == true) {
-        if (netif_queue_stopped(pDevice->dev))
-            netif_wake_queue(pDevice->dev);
-    }
+       if (pDevice->bLinkPass == true) {
+               if (pMgmt->eAuthenMode < WMAC_AUTH_WPA ||
+                       pDevice->fWPA_Authened == true) {
+                       if (++pDevice->tx_data_time_out > 40) {
+                               pDevice->tx_trigger = true;
+
+                               PSbSendNullPacket(pDevice);
+
+                               pDevice->tx_trigger = false;
+                               pDevice->tx_data_time_out = 0;
+                       }
+               }
+
+               if (netif_queue_stopped(pDevice->dev))
+                       netif_wake_queue(pDevice->dev);
+       }
 
     spin_unlock_irq(&pDevice->lock);
 
-    pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
-    add_timer(&pMgmt->sTimerSecondCallback);
+       schedule_delayed_work(&pDevice->second_callback_work, HZ);
 }
 
 /*+
index bce3b46541656f71a603ad6d402db19813f7e2c3..fc418555bc4d983dcc98a3776440ea86374dabe1 100644 (file)
@@ -262,7 +262,7 @@ void BSSvCreateOneNode(struct vnt_private *, u32 *puNodeIndex);
 void BSSvUpdateAPNode(struct vnt_private *, u16 *pwCapInfo,
        PWLAN_IE_SUPP_RATES pItemRates, PWLAN_IE_SUPP_RATES pExtSuppRates);
 
-void BSSvSecondCallBack(struct vnt_private *);
+void BSSvSecondCallBack(struct work_struct *work);
 
 void BSSvUpdateNodeTxCounter(struct vnt_private *, PSStatCounter pStatistic,
        u8 byTSR, u8 byPktNO);
index 5158ff4b346a135db1dda3cc225f1e4405cc5edd..e430b35463b6b3595aa52a7fa8bb4962c9aff0f0 100644 (file)
@@ -403,7 +403,7 @@ exit:
 
 void CHvInitChannelTable(struct vnt_private *pDevice)
 {
-       int bMultiBand = false;
+       bool bMultiBand = false;
        int ii;
 
     for (ii = 1; ii <= CB_MAX_CHANNEL; ii++)
index 4675135aa2583c67c80693889eeffd0e23339440..afe7074c3037e37614121f12077b277fa86cecde 100644 (file)
 /*
  * TX FIFO header
  */
-typedef struct tagSTxBufHead {
-       u32 adwTxKey[4];
-    u16    wFIFOCtl;
-    u16    wTimeStamp;
-    u16    wFragCtl;
-    u16    wReserved;
-} __attribute__ ((__packed__))
-STxBufHead, *PSTxBufHead;
-typedef const STxBufHead *PCSTxBufHead;
 
 typedef struct tagSTxShortBufHead {
     u16    wFIFOCtl;
index 8e396341c5e84aad180e15acbf4d06e74d6a276d..62b7de19b371d2cc7635de9fa339b2b7b78a0143 100644 (file)
@@ -384,8 +384,8 @@ struct vnt_private {
 
        struct tasklet_struct CmdWorkItem;
        struct tasklet_struct EventWorkItem;
-       struct tasklet_struct ReadWorkItem;
-       struct tasklet_struct RxMngWorkItem;
+       struct work_struct read_work_item;
+       struct work_struct rx_mng_work_item;
 
        u32 rx_buf_sz;
        int multicast_limit;
@@ -579,6 +579,9 @@ struct vnt_private {
        u8 abyOFDMAPwrTbl[42];
 
        u16 wCurrentRate;
+       u16 tx_rate_fb0;
+       u16 tx_rate_fb1;
+
        u16 wRTSThreshold;
        u16 wFragmentationThreshold;
        u8 byShortRetryLimit;
@@ -707,13 +710,12 @@ struct vnt_private {
        u8 byBBCR09;
 
        /* command timer */
-       struct timer_list sTimerCommand;
-
-       struct timer_list sTimerTxData;
-       unsigned long nTxDataTimeCout;
-       int fTxDataInSleep;
-       int IsTxDataTrigger;
+       struct delayed_work run_command_work;
+       /* One second callback */
+       struct delayed_work second_callback_work;
 
+       u8 tx_data_time_out;
+       bool tx_trigger;
        int fWPA_Authened; /*is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? */
        u8 byReAssocCount;
        u8 byLinkWaitCount;
index ea7d443b11d067c22f07f41c5c8ac7d2f6fecb03..75dc92d64056a3c30ef25698196fa1c3e4ce326f 100644 (file)
@@ -136,9 +136,9 @@ static void s_vProcessRxMACHeader(struct vnt_private *pDevice,
     };
 
     pbyRxBuffer = (u8 *) (pbyRxBufferAddr + cbHeaderSize);
-    if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
+    if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_Bridgetunnel)) {
         cbHeaderSize += 6;
-    } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
+    } else if (ether_addr_equal(pbyRxBuffer, pDevice->abySNAP_RFC1042)) {
         cbHeaderSize += 6;
         pwType = (u16 *) (pbyRxBufferAddr + cbHeaderSize);
        if ((*pwType == cpu_to_be16(ETH_P_IPX)) ||
@@ -361,7 +361,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB,
     if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
         (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
        if (pMgmt->sNodeDBTable[0].bActive) {
-        if (!compare_ether_addr(pMgmt->abyCurrBSSID, pMACHeader->addr2)) {
+        if (ether_addr_equal(pMgmt->abyCurrBSSID, pMACHeader->addr2)) {
            if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
                   pMgmt->sNodeDBTable[0].uInActiveCount = 0;
            }
@@ -374,8 +374,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB,
             return false;
         }
 
-       if (compare_ether_addr(pDevice->abyCurrentNetAddr,
-                              pMACHeader->addr1)) {
+       if (!ether_addr_equal(pDevice->abyCurrentNetAddr, pMACHeader->addr1)) {
                return false;
         }
     }
@@ -383,8 +382,8 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB,
     // Use for TKIP MIC
     s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader);
 
-    if (!compare_ether_addr((u8 *)&(pDevice->sRxEthHeader.h_source[0]),
-                           pDevice->abyCurrentNetAddr))
+    if (ether_addr_equal((u8 *)pDevice->sRxEthHeader.h_source,
+                        pDevice->abyCurrentNetAddr))
         return false;
 
     if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
@@ -560,7 +559,7 @@ int RXbBulkInProcessData(struct vnt_private *pDevice, struct vnt_rcb *pRCB,
             }
             if (pDevice->bIsRxMngWorkItemQueued == false) {
                 pDevice->bIsRxMngWorkItemQueued = true;
-                tasklet_schedule(&pDevice->RxMngWorkItem);
+               schedule_work(&pDevice->rx_mng_work_item);
             }
 
         }
@@ -1333,11 +1332,16 @@ static int s_bAPModeRxData(struct vnt_private *pDevice, struct sk_buff *skb,
     return true;
 }
 
-void RXvWorkItem(struct vnt_private *pDevice)
+void RXvWorkItem(struct work_struct *work)
 {
+       struct vnt_private *pDevice =
+               container_of(work, struct vnt_private, read_work_item);
        int ntStatus;
        struct vnt_rcb *pRCB = NULL;
 
+       if (pDevice->Flags & fMP_DISCONNECTED)
+               return;
+
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Polling Thread\n");
     spin_lock_irq(&pDevice->lock);
 
@@ -1384,17 +1388,22 @@ void RXvFreeRCB(struct vnt_rcb *pRCB, int bReAllocSkb)
         (pDevice->bIsRxWorkItemQueued == false) ) {
 
         pDevice->bIsRxWorkItemQueued = true;
-        tasklet_schedule(&pDevice->ReadWorkItem);
+       schedule_work(&pDevice->read_work_item);
     }
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----RXFreeRCB %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
 }
 
-void RXvMngWorkItem(struct vnt_private *pDevice)
+void RXvMngWorkItem(struct work_struct *work)
 {
+       struct vnt_private *pDevice =
+               container_of(work, struct vnt_private, rx_mng_work_item);
        struct vnt_rcb *pRCB = NULL;
        struct vnt_rx_mgmt *pRxPacket;
        int bReAllocSkb = false;
 
+       if (pDevice->Flags & fMP_DISCONNECTED)
+               return;
+
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Mng Thread\n");
 
     spin_lock_irq(&pDevice->lock);
index 95388dc03ee3993731818fde811342d4f5fbb473..8d524345dfdb943a79df7e027b70f54df6ca9a30 100644 (file)
@@ -32,9 +32,9 @@
 #include "device.h"
 #include "wcmd.h"
 
-void RXvWorkItem(void *Context);
+void RXvWorkItem(struct work_struct *work);
 
-void RXvMngWorkItem(void *Context);
+void RXvMngWorkItem(struct work_struct *work);
 
 void RXvFreeRCB(struct vnt_rcb *pRCB, int bReAllocSkb);
 
index a1dc3a4cfd9c1e6a47583ea425cfb42ab7d59404..cd2ea76c8b1e1ee70eda84d70cdcce6117978dce 100644 (file)
@@ -35,8 +35,8 @@
 #include "control.h"
 #include "rndis.h"
 
-static int          msglevel                =MSG_LEVEL_INFO;
-//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int msglevel = MSG_LEVEL_INFO;
+/* static int msglevel = MSG_LEVEL_DEBUG; */
 
 #define FIRMWARE_VERSION       0x133           /* version 1.51 */
 #define FIRMWARE_NAME          "vntwusb.fw"
@@ -72,18 +72,17 @@ int FIRMWAREbDownload(struct vnt_private *pDevice)
                memcpy(pBuffer, fw->data + ii, wLength);
 
                NdisStatus = CONTROLnsRequestOutAsyn(pDevice,
-                                            0,
-                                            0x1200+ii,
-                                            0x0000,
-                                            wLength,
-                                            pBuffer
-                                            );
+                                               0,
+                                               0x1200+ii,
+                                               0x0000,
+                                               wLength,
+                                               pBuffer);
 
                DBG_PRT(MSG_LEVEL_DEBUG,
                        KERN_INFO"Download firmware...%d %zu\n", ii, fw->size);
                if (NdisStatus != STATUS_SUCCESS)
                        goto free_fw;
-        }
+       }
 
        result = true;
 free_fw:
@@ -101,48 +100,47 @@ int FIRMWAREbBrach2Sram(struct vnt_private *pDevice)
 {
        int NdisStatus;
 
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Branch to Sram\n");
-
-    NdisStatus = CONTROLnsRequestOut(pDevice,
-                                    1,
-                                    0x1200,
-                                    0x0000,
-                                    0,
-                                    NULL
-                                    );
-
-    if (NdisStatus != STATUS_SUCCESS) {
-        return (false);
-    } else {
-        return (true);
-    }
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Branch to Sram\n");
+
+       NdisStatus = CONTROLnsRequestOut(pDevice,
+                                       1,
+                                       0x1200,
+                                       0x0000,
+                                       0,
+                                       NULL);
+       if (NdisStatus != STATUS_SUCCESS)
+               return false;
+       else
+               return true;
 }
 
 int FIRMWAREbCheckVersion(struct vnt_private *pDevice)
 {
        int ntStatus;
 
-    ntStatus = CONTROLnsRequestIn(pDevice,
-                                    MESSAGE_TYPE_READ,
-                                    0,
-                                    MESSAGE_REQUEST_VERSION,
-                                    2,
-                                    (u8 *) &(pDevice->wFirmwareVersion));
-
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion);
-    if (ntStatus != STATUS_SUCCESS) {
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Invalid.\n");
-        return false;
-    }
-    if (pDevice->wFirmwareVersion == 0xFFFF) {
-        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"In Loader.\n");
-        return false;
-    }
-    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion);
-    if (pDevice->wFirmwareVersion < FIRMWARE_VERSION) {
-        // branch to loader for download new firmware
-        FIRMWAREbBrach2Sram(pDevice);
-        return false;
-    }
-    return true;
+       ntStatus = CONTROLnsRequestIn(pDevice,
+                                       MESSAGE_TYPE_READ,
+                                       0,
+                                       MESSAGE_REQUEST_VERSION,
+                                       2,
+                                       (u8 *) &(pDevice->wFirmwareVersion));
+
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n",
+                                               pDevice->wFirmwareVersion);
+       if (ntStatus != STATUS_SUCCESS) {
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Invalid.\n");
+               return false;
+       }
+       if (pDevice->wFirmwareVersion == 0xFFFF) {
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"In Loader.\n");
+               return false;
+       }
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n",
+                                               pDevice->wFirmwareVersion);
+       if (pDevice->wFirmwareVersion < FIRMWARE_VERSION) {
+               /* branch to loader for download new firmware */
+               FIRMWAREbBrach2Sram(pDevice);
+               return false;
+       }
+       return true;
 }
index c699a3058b39920a34daf1a6f63524be990e29cb..7d96fe7a3e416f7b190e02685decab636e40b333 100644 (file)
@@ -414,7 +414,7 @@ static int hostap_set_encryption(struct vnt_private *pDevice,
        int ret = 0;
        s32 iNodeIndex = -1;
        int ii;
-       int bKeyTableFull = false;
+       bool bKeyTableFull = false;
        u16 wKeyCtl = 0;
 
        param->u.crypt.err = 0;
index 8872e0f84f40e825efec5dd7f7614f6c22f43562..63917abbbd006b8672c4ec8e5124fd9e85ffea63 100644 (file)
@@ -60,7 +60,7 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
        pDevice->wstats.status = pDevice->eOPMode;
        if (pDevice->scStatistic.LinkQuality > 100)
                pDevice->scStatistic.LinkQuality = 100;
-       pDevice->wstats.qual.qual =(u8)pDevice->scStatistic.LinkQuality;
+       pDevice->wstats.qual.qual = (u8)pDevice->scStatistic.LinkQuality;
        RFvRSSITodBm(pDevice, (u8)(pDevice->uCurrRSSI), &ldBm);
        pDevice->wstats.qual.level = ldBm;
        pDevice->wstats.qual.noise = 0;
@@ -190,7 +190,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
                return -EAGAIN;
        }
        pBSS = &(pMgmt->sBSSList[0]);
-       for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
+       for (ii = 0, jj = 0; jj < MAX_BSS_NUM; jj++) {
                if (current_ev >= end_buf)
                        break;
                pBSS = &(pMgmt->sBSSList[jj]);
@@ -225,7 +225,7 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info,
                        iwe.u.freq.m = pBSS->uChannel;
                        iwe.u.freq.e = 0;
                        iwe.u.freq.i = 0;
-                       current_ev = iwe_stream_add_event(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
+                       current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
                        {
                                int f = (int)pBSS->uChannel - 1;
                                if (f < 0)
@@ -400,7 +400,7 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
                        if (pDevice->flags & DEVICE_FLAGS_OPENED)
                                pDevice->bCommit = true;
                }
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc\n");
                break;
        case IW_MODE_AUTO:
        case IW_MODE_INFRA:
@@ -409,7 +409,7 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
                        if (pDevice->flags & DEVICE_FLAGS_OPENED)
                                pDevice->bCommit = true;
                }
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure\n");
                break;
        case IW_MODE_MASTER:
 
@@ -422,7 +422,7 @@ int iwctl_siwmode(struct net_device *dev, struct iw_request_info *info,
                        if (pDevice->flags & DEVICE_FLAGS_OPENED)
                                pDevice->bCommit = true;
                }
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point\n");
                break;
 
        case IW_MODE_REPEAT:
@@ -657,8 +657,8 @@ int iwctl_siwap(struct net_device *dev, struct iw_request_info *info,
                        unsigned uSameBssidNum = 0;
                        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                                if (pMgmt->sBSSList[ii].bActive &&
-                                       !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
-                                                       pMgmt->abyDesireBSSID)) {
+                                       ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                                        pMgmt->abyDesireBSSID)) {
                                        uSameBssidNum++;
                                }
                        }
@@ -786,8 +786,8 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
        if (wrq->flags == 0) {
                // Just send an empty SSID list
                memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-               memset(pMgmt->abyDesireBSSID, 0xFF,6);
-               PRINT_K("set essid to 'any' \n");
+               memset(pMgmt->abyDesireBSSID, 0xFF, 6);
+               PRINT_K("set essid to 'any'\n");
                // Unknown desired AP, so here need not associate??
                return 0;
        } else {
@@ -798,15 +798,15 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
 
                memcpy(pItemSSID->abySSID, extra, wrq->length);
                if (pItemSSID->abySSID[wrq->length] == '\0') {
-                       if (wrq->length>0)
+                       if (wrq->length > 0)
                                pItemSSID->len = wrq->length;
                } else {
                        pItemSSID->len = wrq->length;
                }
-               PRINT_K("set essid to %s \n", pItemSSID->abySSID);
+               PRINT_K("set essid to %s\n", pItemSSID->abySSID);
 
                // mike: need clear desiredBSSID
-               if (pItemSSID->len==0) {
+               if (pItemSSID->len == 0) {
                        memset(pMgmt->abyDesireBSSID, 0xFF, 6);
                        return 0;
                }
@@ -840,8 +840,8 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
                                // are two same BSSID exist in list ?
                                for (ii = 0; ii < MAX_BSS_NUM; ii++) {
                                        if (pMgmt->sBSSList[ii].bActive &&
-                                               !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID,
-                                                               pCurr->abyBSSID)) {
+                                               ether_addr_equal(pMgmt->sBSSList[ii].abyBSSID,
+                                                                pCurr->abyBSSID)) {
                                                uSameBssidNum++;
                                        }
                                }
@@ -860,7 +860,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info,
                        return 0;
                }
 
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s\n", pItemSSID->abySSID);
        }
 
        if (pDevice->flags & DEVICE_FLAGS_OPENED)
@@ -893,7 +893,7 @@ int iwctl_giwessid(struct net_device *dev, struct iw_request_info *info,
        memcpy(extra, pItemSSID->abySSID, pItemSSID->len);
        extra[pItemSSID->len] = '\0';
 
-        wrq->length = pItemSSID->len;
+       wrq->length = pItemSSID->len;
        wrq->flags = 1; // active
 
        return 0;
@@ -915,7 +915,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
                0x60, 0x6C, 0x90
        };
 
-       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE\n");
        if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
                rc = -EINVAL;
                return rc;
@@ -953,7 +953,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
        }
        // Check that it is valid
        // brate is index of abySupportedRates[]
-       if (brate > 13 ) {
+       if (brate > 13) {
                rc = -EINVAL;
                return rc;
        }
@@ -967,7 +967,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_request_info *info,
                        pDevice->uConnectionRate = 3;
                } else {
                        pDevice->uConnectionRate = brate;
-                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
+                       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d\n", pDevice->uConnectionRate);
                }
        } else {
                pDevice->bFixRate = false;
@@ -1017,7 +1017,7 @@ int iwctl_giwrate(struct net_device *dev, struct iw_request_info *info,
                        if (pDevice->byBBType == BB_TYPE_11A)
                                brate = 0x6C;
                }
-               if (pDevice->uConnectionRate == 13)
+               if (pDevice->uConnectionRate == 13)
                        brate = abySupportedRates[pDevice->wCurrentRate];
                wrq->value = brate * 500000;
                // If more than one rate, set auto
@@ -1286,7 +1286,7 @@ int iwctl_giwencode(struct net_device *dev, struct iw_request_info *info,
        if (index < 1) { // get default key
                if (pDevice->byKeyIndex < WLAN_WEP_NKEYS)
                        index = pDevice->byKeyIndex;
-               else
+               else
                        index = 0;
        } else {
                index--;
@@ -1366,14 +1366,14 @@ int iwctl_siwpower(struct net_device *dev, struct iw_request_info *info,
 
        switch (wrq->flags & IW_POWER_MODE) {
        case IW_POWER_UNICAST_R:
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R\n");
                rc = -EINVAL;
                break;
        case IW_POWER_ALL_R:
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R\n");
                rc = -EINVAL;
        case IW_POWER_ON:
-               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON\n");
                break;
        default:
                rc = -EINVAL;
@@ -1465,7 +1465,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
        case IW_AUTH_CIPHER_PAIRWISE:
                pairwise = wrq->value;
                PRINT_K("iwctl_siwauth:set pairwise=%d\n", pairwise);
-               if (pairwise == IW_AUTH_CIPHER_CCMP){
+               if (pairwise == IW_AUTH_CIPHER_CCMP) {
                        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
                } else if (pairwise == IW_AUTH_CIPHER_TKIP) {
                        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
@@ -1490,13 +1490,13 @@ int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info,
                }
                break;
        case IW_AUTH_KEY_MGMT:
-               PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n", wpa_version,wrq->value);
-               if (wpa_version == IW_AUTH_WPA_VERSION_WPA2){
+               PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n", wpa_version, wrq->value);
+               if (wpa_version == IW_AUTH_WPA_VERSION_WPA2) {
                        if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
                                pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
                        else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
                } else if (wpa_version == IW_AUTH_WPA_VERSION_WPA) {
-                       if (wrq->value == 0){
+                       if (wrq->value == 0) {
                                pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
                        } else if (wrq->value == IW_AUTH_KEY_MGMT_PSK)
                                pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
@@ -1558,17 +1558,17 @@ int iwctl_siwgenie(struct net_device *dev, struct iw_request_info *info,
        if (pMgmt == NULL)
                return -EFAULT;
 
-       if (wrq->length){
+       if (wrq->length) {
                if ((wrq->length < 2) || (extra[1] + 2 != wrq->length)) {
                        ret = -EINVAL;
                        goto out;
                }
-               if (wrq->length > MAX_WPA_IE_LEN){
+               if (wrq->length > MAX_WPA_IE_LEN) {
                        ret = -ENOMEM;
                        goto out;
                }
                memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
-               if (copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){
+               if (copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)) {
                        ret = -EFAULT;
                        goto out;
                }
@@ -1615,7 +1615,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        struct iw_point *wrq = &wrqu->encoding;
        struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
-       struct viawget_wpa_param *param=NULL;
+       struct viawget_wpa_param *param = NULL;
 // original member
        wpa_alg alg_name;
        u8 addr[6];
@@ -1658,8 +1658,8 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
                alg_name = WPA_ALG_CCMP;
                break;
        default:
-               PRINT_K("Unknown alg = %d\n",ext->alg);
-               ret= -ENOMEM;
+               PRINT_K("Unknown alg = %d\n", ext->alg);
+               ret = -ENOMEM;
                goto error;
        }
 // recover addr
@@ -1671,7 +1671,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
                set_tx = 1;
 // recover seq,seq_len
        if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
-               seq_len=IW_ENCODE_SEQ_MAX_SIZE;
+               seq_len = IW_ENCODE_SEQ_MAX_SIZE;
                memcpy(seq, ext->rx_seq, seq_len);
        }
 // recover key,key_len
@@ -1702,7 +1702,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info,
 /****set if current action is Network Manager count?? */
 /****this method is so foolish,but there is no other way??? */
        if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
-               if (param->u.wpa_key.key_index ==0) {
+               if (param->u.wpa_key.key_index == 0) {
                        pDevice->bwextstep0 = true;
                }
                if ((pDevice->bwextstep0 == true) && (param->u.wpa_key.key_index == 1)) {
@@ -1761,7 +1761,7 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info,
                ret = -EINVAL;
                return ret;
        }
-       switch (mlme->cmd){
+       switch (mlme->cmd) {
        case IW_MLME_DEAUTH:
        case IW_MLME_DISASSOC:
                if (pDevice->bLinkPass == true) {
@@ -1815,7 +1815,6 @@ static const iw_handler iwctl_handler[] = {
        IW_HANDLER(SIOCGIWPOWER, iwctl_giwpower),
        IW_HANDLER(SIOCSIWGENIE, iwctl_siwgenie),
        IW_HANDLER(SIOCGIWGENIE, iwctl_giwgenie),
-       IW_HANDLER(SIOCSIWMLME, iwctl_siwmlme),
        IW_HANDLER(SIOCSIWAUTH, iwctl_siwauth),
        IW_HANDLER(SIOCGIWAUTH, iwctl_giwauth),
        IW_HANDLER(SIOCSIWENCODEEXT, iwctl_siwencodeext),
index 205590b0e9c839018a390cd79a0c23fe97d341ec..be92c048a12e93bbd6169e0b2d54fb1c6c0503f9 100644 (file)
@@ -151,7 +151,7 @@ int KeybGetKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyIndex,
     *pKey = NULL;
     for (i=0;i<MAX_KEY_TABLE;i++) {
         if ((pTable->KeyTable[i].bInUse == true) &&
-           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+           ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             if (dwKeyIndex == 0xFFFFFFFF) {
                 if (pTable->KeyTable[i].PairwiseKey.bKeyValid == true) {
                     *pKey = &(pTable->KeyTable[i].PairwiseKey);
@@ -213,7 +213,7 @@ int KeybSetKey(struct vnt_private *pDevice, PSKeyManagement pTable,
             j = i;
         }
         if ((pTable->KeyTable[i].bInUse == true) &&
-           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+           ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             // found table already exist
             if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                 // Pairwise key
@@ -395,7 +395,7 @@ int KeybRemoveKey(struct vnt_private *pDevice, PSKeyManagement pTable,
     } else {
         for (i=0;i<MAX_KEY_TABLE;i++) {
             if ( (pTable->KeyTable[i].bInUse == true) &&
-                !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+                ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
 
                 if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
                     pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
@@ -445,7 +445,7 @@ int KeybRemoveAllKey(struct vnt_private *pDevice, PSKeyManagement pTable,
 
     for (i=0;i<MAX_KEY_TABLE;i++) {
         if ((pTable->KeyTable[i].bInUse == true) &&
-           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+           ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
             pTable->KeyTable[i].PairwiseKey.bKeyValid = false;
            for (u = 0; u < MAX_GROUP_KEY; u++)
                pTable->KeyTable[i].GroupKey[u].bKeyValid = false;
@@ -480,7 +480,7 @@ int KeybGetTransmitKey(PSKeyManagement pTable, u8 *pbyBSSID, u32 dwKeyType,
 
     for (i = 0; i < MAX_KEY_TABLE; i++) {
         if ((pTable->KeyTable[i].bInUse == true) &&
-           !compare_ether_addr(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
+           ether_addr_equal(pTable->KeyTable[i].abyBSSID, pbyBSSID)) {
 
             if (dwKeyType == PAIRWISE_KEY) {
 
index 6f9d28182445ce99b2d37bcd37aaae3c3d2bdc03..5e4a5d0988d7ed9544a17a9274b7b777b2a8e0f5 100644 (file)
@@ -702,6 +702,16 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        device_set_options(pDevice);
        spin_lock_init(&pDevice->lock);
+       INIT_DELAYED_WORK(&pDevice->run_command_work, vRunCommand);
+       INIT_DELAYED_WORK(&pDevice->second_callback_work, BSSvSecondCallBack);
+       INIT_WORK(&pDevice->read_work_item, RXvWorkItem);
+       INIT_WORK(&pDevice->rx_mng_work_item, RXvMngWorkItem);
+
+       pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!pDevice->pControlURB) {
+               DBG_PRT(MSG_LEVEL_ERR, KERN_ERR"Failed to alloc control urb\n");
+               goto err_netdev;
+       }
 
        pDevice->tx_80211 = device_dma0_tx_80211;
        pDevice->vnt_mgmt.pAdapter = (void *) pDevice;
@@ -849,23 +859,15 @@ static bool device_alloc_bufs(struct vnt_private *pDevice)
         pRCB++;
     }
 
-       pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
-       if (pDevice->pControlURB == NULL) {
-           DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
-           goto free_rx_tx;
-       }
-
        pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
        if (pDevice->pInterruptURB == NULL) {
            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
-           usb_free_urb(pDevice->pControlURB);
            goto free_rx_tx;
        }
 
     pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
        if (pDevice->intBuf.pDataBuf == NULL) {
            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
-           usb_free_urb(pDevice->pControlURB);
            usb_free_urb(pDevice->pInterruptURB);
            goto free_rx_tx;
        }
@@ -981,10 +983,11 @@ static int  device_open(struct net_device *dev)
     }
 
     vMgrObjectInit(pDevice);
-    tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
-    tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
+
     tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
-       add_timer(&pDevice->vnt_mgmt.sTimerSecondCallback);
+
+       schedule_delayed_work(&pDevice->second_callback_work, HZ);
+
        pDevice->int_interval = 100;  /* max 100 microframes */
     pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
 
@@ -1000,7 +1003,7 @@ static int  device_open(struct net_device *dev)
      pDevice->bWPASuppWextEnabled = false;
     pDevice->byReAssocCount = 0;
 
-    RXvWorkItem(pDevice);
+       schedule_work(&pDevice->read_work_item);
     INTvWorkItem(pDevice);
 
     /* if WEP key already set by iwconfig but device not yet open */
@@ -1035,9 +1038,7 @@ free_rx_tx:
     device_free_rx_bufs(pDevice);
     device_free_tx_bufs(pDevice);
     device_free_int_bufs(pDevice);
-       usb_kill_urb(pDevice->pControlURB);
        usb_kill_urb(pDevice->pInterruptURB);
-    usb_free_urb(pDevice->pControlURB);
     usb_free_urb(pDevice->pInterruptURB);
 
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
@@ -1076,18 +1077,19 @@ static int device_close(struct net_device *dev)
     MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
     MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
     pDevice->fKillEventPollingThread = true;
-    del_timer(&pDevice->sTimerCommand);
-    del_timer(&pMgmt->sTimerSecondCallback);
 
-    del_timer(&pDevice->sTimerTxData);
+       cancel_delayed_work_sync(&pDevice->run_command_work);
+       cancel_delayed_work_sync(&pDevice->second_callback_work);
 
     if (pDevice->bDiversityRegCtlON) {
         del_timer(&pDevice->TimerSQ3Tmax1);
         del_timer(&pDevice->TimerSQ3Tmax2);
         del_timer(&pDevice->TimerSQ3Tmax3);
     }
-    tasklet_kill(&pDevice->RxMngWorkItem);
-    tasklet_kill(&pDevice->ReadWorkItem);
+
+       cancel_work_sync(&pDevice->rx_mng_work_item);
+       cancel_work_sync(&pDevice->read_work_item);
+
     tasklet_kill(&pDevice->EventWorkItem);
 
    pDevice->bRoaming = false;
@@ -1105,9 +1107,7 @@ static int device_close(struct net_device *dev)
     device_free_int_bufs(pDevice);
     device_free_frag_bufs(pDevice);
 
-       usb_kill_urb(pDevice->pControlURB);
        usb_kill_urb(pDevice->pInterruptURB);
-    usb_free_urb(pDevice->pControlURB);
     usb_free_urb(pDevice->pInterruptURB);
 
     BSSvClearNodeDBTable(pDevice, 0);
@@ -1131,9 +1131,12 @@ static void vt6656_disconnect(struct usb_interface *intf)
 
        if (device->dev) {
                unregister_netdev(device->dev);
+
+               usb_kill_urb(device->pControlURB);
+               usb_free_urb(device->pControlURB);
+
                free_netdev(device->dev);
        }
-
 }
 
 static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev)
index edc8975b2e2a0ceae17aabea15813285cd8c3846..6334315807bb43844848e50e5173cb93f21cda82 100644 (file)
@@ -257,10 +257,8 @@ int PSbSendNullPacket(struct vnt_private *pDevice)
        if (pDevice->bLinkPass == false)
                return false;
 
-       if ((pDevice->bEnablePSMode == false) &&
-               (pDevice->fTxDataInSleep == false)) {
-                       return false;
-       }
+       if (pDevice->bEnablePSMode == false && pDevice->tx_trigger == false)
+               return false;
 
        memset(pMgmt->pbyPSPacketPool, 0, sizeof(struct vnt_tx_mgmt)
                + WLAN_NULLDATA_FR_MAXLEN);
index 14f3e852215da5fb27702b4b91687047b9a290c2..35a3ddb41a6a2f4ac7ee36ad55a55549ee7569e0 100644 (file)
@@ -98,21 +98,18 @@ static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
 
 static void *s_vGetFreeContext(struct vnt_private *pDevice);
 
-static void s_vGenerateTxParameter(struct vnt_private *pDevice,
-       u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
-       void *rts_cts, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
-       struct ethhdr *psEthHeader, bool need_rts);
-
-static u32 s_uFillDataHead(struct vnt_private *pDevice,
-       u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
-       u32 uDMAIdx, int bNeedAck, u8 byFBOption);
+static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
+       u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer,
+       struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize,
+       int bNeedACK, u32 uDMAIdx, struct ethhdr *psEthHeader, bool need_rts);
 
 static void s_vGenerateMACHeader(struct vnt_private *pDevice,
        u8 *pbyBufferAddr, u16 wDuration, struct ethhdr *psEthHeader,
        int bNeedEncrypt, u16 wFragType, u32 uDMAIdx, u32 uFragIdx);
 
-static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
-       u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
+static void s_vFillTxKey(struct vnt_private *pDevice,
+       struct vnt_tx_fifo_head *fifo_head, u8 *pbyIVHead,
+       PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
        struct vnt_mic_hdr *mic_hdr);
 
 static void s_vSWencryption(struct vnt_private *pDevice,
@@ -124,11 +121,11 @@ static unsigned int s_uGetTxRsvTime(struct vnt_private *pDevice, u8 byPktType,
 static u16 s_uGetRTSCTSRsvTime(struct vnt_private *pDevice, u8 byRTSRsvType,
        u8 byPktType, u32 cbFrameLength, u16 wCurrentRate);
 
-static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
+static u16 s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
        u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength,
        int bNeedAck, u16 wCurrentRate, u8 byFBOption);
 
-static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
+static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
        union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck,
        struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption);
 
@@ -183,10 +180,12 @@ static void s_vSaveTxPktInfo(struct vnt_private *pDevice, u8 byPktNum,
           ETH_ALEN);
 }
 
-static void s_vFillTxKey(struct vnt_private *pDevice, u8 *pbyBuf,
-       u8 *pbyIVHead, PSKeyItem pTransmitKey, u8 *pbyHdrBuf,
-       u16 wPayloadLen, struct vnt_mic_hdr *mic_hdr)
+static void s_vFillTxKey(struct vnt_private *pDevice,
+       struct vnt_tx_fifo_head *fifo_head, u8 *pbyIVHead,
+       PSKeyItem pTransmitKey, u8 *pbyHdrBuf, u16 wPayloadLen,
+       struct vnt_mic_hdr *mic_hdr)
 {
+       u8 *pbyBuf = (u8 *)&fifo_head->adwTxKey[0];
        u32 *pdwIV = (u32 *)pbyIVHead;
        u32 *pdwExtIV = (u32 *)((u8 *)pbyIVHead + 4);
        struct ieee80211_hdr *pMACHeader = (struct ieee80211_hdr *)pbyHdrBuf;
@@ -431,185 +430,114 @@ static u16 s_uGetRTSCTSDuration(struct vnt_private *pDevice, u8 byDurType,
 {
        u32 uCTSTime = 0, uDurTime = 0;
 
-    switch (byDurType) {
+       switch (byDurType) {
+       case RTSDUR_BB:
+       case RTSDUR_BA:
+       case RTSDUR_BA_F0:
+       case RTSDUR_BA_F1:
+               uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType,
+                       14, pDevice->byTopCCKBasicRate);
+               uDurTime = uCTSTime + 2 * pDevice->uSIFS +
+                       s_uGetTxRsvTime(pDevice, byPktType,
+                                               cbFrameLength, wRate, bNeedAck);
+               break;
 
-    case RTSDUR_BB:    //RTSDuration_bb
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
-        break;
+       case RTSDUR_AA:
+       case RTSDUR_AA_F0:
+       case RTSDUR_AA_F1:
+               uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType,
+                       14, pDevice->byTopOFDMBasicRate);
+               uDurTime = uCTSTime + 2 * pDevice->uSIFS +
+                       s_uGetTxRsvTime(pDevice, byPktType,
+                                               cbFrameLength, wRate, bNeedAck);
+               break;
 
-    case RTSDUR_BA:    //RTSDuration_ba
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
-        break;
+       case CTSDUR_BA:
+       case CTSDUR_BA_F0:
+       case CTSDUR_BA_F1:
+               uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice,
+                               byPktType, cbFrameLength, wRate, bNeedAck);
+               break;
 
-    case RTSDUR_AA:    //RTSDuration_aa
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
-        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
-        break;
+       default:
+               break;
+       }
 
-    case CTSDUR_BA:    //CTSDuration_ba
-        uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
-        break;
+       return cpu_to_le16((u16)uDurTime);
+}
 
-    case RTSDUR_BA_F0: //RTSDuration_ba_f0
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        }
-        break;
-
-    case RTSDUR_AA_F0: //RTSDuration_aa_f0
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        }
-        break;
+static u16 vnt_rxtx_datahead_g(struct vnt_private *priv, u8 pkt_type, u16 rate,
+               struct vnt_tx_datahead_g *buf, u32 frame_len, int need_ack)
+{
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
+       BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate,
+                                                       PK_TYPE_11B, &buf->b);
 
-    case RTSDUR_BA_F1: //RTSDuration_ba_f1
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        }
-        break;
-
-    case RTSDUR_AA_F1: //RTSDuration_aa_f1
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        }
-        break;
+       /* Get Duration and TimeStamp */
+       buf->wDuration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
 
-    case CTSDUR_BA_F0: //CTSDuration_ba_f0
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
-        }
-        break;
+       buf->wTimeStampOff_a = vnt_time_stamp_off(priv, rate);
+       buf->wTimeStampOff_b = vnt_time_stamp_off(priv,
+                                       priv->byTopCCKBasicRate);
 
-    case CTSDUR_BA_F1: //CTSDuration_ba_f1
-        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
-            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
-        }
-        break;
+       return buf->wDuration_a;
+}
 
-    default:
-        break;
-    }
+static u16 vnt_rxtx_datahead_g_fb(struct vnt_private *priv, u8 pkt_type,
+               u16 rate, struct vnt_tx_datahead_g_fb *buf,
+               u32 frame_len, int need_ack)
+{
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
 
-       return cpu_to_le16((u16)uDurTime);
+       BBvCalculateParameter(priv, frame_len, priv->byTopCCKBasicRate,
+                                               PK_TYPE_11B, &buf->b);
+
+       /* Get Duration and TimeStamp */
+       buf->wDuration_a = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_b = s_uGetDataDuration(priv, PK_TYPE_11B, need_ack);
+
+       buf->wDuration_a_f0 = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_a_f1 = s_uGetDataDuration(priv, pkt_type, need_ack);
+
+       buf->wTimeStampOff_a = vnt_time_stamp_off(priv, rate);
+       buf->wTimeStampOff_b = vnt_time_stamp_off(priv,
+                                               priv->byTopCCKBasicRate);
+
+       return buf->wDuration_a;
 }
 
-static u32 s_uFillDataHead(struct vnt_private *pDevice,
-       u8 byPktType, u16 wCurrentRate, void *pTxDataHead, u32 cbFrameLength,
-       u32 uDMAIdx, int bNeedAck, u8 byFBOption)
+static u16 vnt_rxtx_datahead_a_fb(struct vnt_private *priv, u8 pkt_type,
+               u16 rate, struct vnt_tx_datahead_a_fb *buf,
+               u32 frame_len, int need_ack)
 {
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->a);
+       /* Get Duration and TimeStampOff */
+       buf->wDuration = s_uGetDataDuration(priv, pkt_type, need_ack);
 
-    if (pTxDataHead == NULL) {
-        return 0;
-    }
+       buf->wDuration_f0 = s_uGetDataDuration(priv, pkt_type, need_ack);
+       buf->wDuration_f1 = s_uGetDataDuration(priv, pkt_type, need_ack);
 
-    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-            if (byFBOption == AUTO_FB_NONE) {
-               struct vnt_tx_datahead_g *pBuf =
-                               (struct vnt_tx_datahead_g *)pTxDataHead;
-                //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->a);
-               BBvCalculateParameter(pDevice, cbFrameLength,
-                       pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b);
-                //Get Duration and TimeStamp
-               pBuf->wDuration_a = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wDuration_b = s_uGetDataDuration(pDevice,
-                                                       PK_TYPE_11B, bNeedAck);
-
-               pBuf->wTimeStampOff_a = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-               pBuf->wTimeStampOff_b = vnt_time_stamp_off(pDevice,
-                                               pDevice->byTopCCKBasicRate);
-                return (pBuf->wDuration_a);
-             } else {
-                // Auto Fallback
-               struct vnt_tx_datahead_g_fb *pBuf =
-                       (struct vnt_tx_datahead_g_fb *)pTxDataHead;
-                //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->a);
-               BBvCalculateParameter(pDevice, cbFrameLength,
-                       pDevice->byTopCCKBasicRate, PK_TYPE_11B, &pBuf->b);
-                //Get Duration and TimeStamp
-               pBuf->wDuration_a = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wDuration_b = s_uGetDataDuration(pDevice,
-                                                       PK_TYPE_11B, bNeedAck);
-               pBuf->wDuration_a_f0 = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wDuration_a_f1 = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wTimeStampOff_a = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-               pBuf->wTimeStampOff_b = vnt_time_stamp_off(pDevice,
-                                               pDevice->byTopCCKBasicRate);
-                return (pBuf->wDuration_a);
-            } //if (byFBOption == AUTO_FB_NONE)
-    }
-    else if (byPktType == PK_TYPE_11A) {
-       if (byFBOption != AUTO_FB_NONE) {
-               struct vnt_tx_datahead_a_fb *pBuf =
-                       (struct vnt_tx_datahead_a_fb *)pTxDataHead;
-            //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->a);
-            //Get Duration and TimeStampOff
-               pBuf->wDuration = s_uGetDataDuration(pDevice,
-                                       byPktType, bNeedAck);
-               pBuf->wDuration_f0 = s_uGetDataDuration(pDevice,
-                                       byPktType, bNeedAck);
-               pBuf->wDuration_f1 = s_uGetDataDuration(pDevice,
-                                                       byPktType, bNeedAck);
-               pBuf->wTimeStampOff = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-            return (pBuf->wDuration);
-        } else {
-               struct vnt_tx_datahead_ab *pBuf =
-                       (struct vnt_tx_datahead_ab *)pTxDataHead;
-            //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->ab);
-            //Get Duration and TimeStampOff
-               pBuf->wDuration = s_uGetDataDuration(pDevice,
-                               byPktType, bNeedAck);
-               pBuf->wTimeStampOff = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-            return (pBuf->wDuration);
-        }
-    }
-    else if (byPktType == PK_TYPE_11B) {
-               struct vnt_tx_datahead_ab *pBuf =
-                       (struct vnt_tx_datahead_ab *)pTxDataHead;
-            //Get SignalField,ServiceField,Length
-               BBvCalculateParameter(pDevice, cbFrameLength, wCurrentRate,
-                       byPktType, &pBuf->ab);
-            //Get Duration and TimeStampOff
-               pBuf->wDuration = s_uGetDataDuration(pDevice,
-                               byPktType, bNeedAck);
-               pBuf->wTimeStampOff = vnt_time_stamp_off(pDevice,
-                                                               wCurrentRate);
-            return (pBuf->wDuration);
-    }
-    return 0;
+       buf->wTimeStampOff = vnt_time_stamp_off(priv, rate);
+
+       return buf->wDuration;
+}
+
+static u16 vnt_rxtx_datahead_ab(struct vnt_private *priv, u8 pkt_type,
+               u16 rate, struct vnt_tx_datahead_ab *buf,
+               u32 frame_len, int need_ack)
+{
+       /* Get SignalField,ServiceField,Length */
+       BBvCalculateParameter(priv, frame_len, rate, pkt_type, &buf->ab);
+       /* Get Duration and TimeStampOff */
+       buf->wDuration = s_uGetDataDuration(priv, pkt_type, need_ack);
+
+       buf->wTimeStampOff = vnt_time_stamp_off(priv, rate);
+
+       return buf->wDuration;
 }
 
 static int vnt_fill_ieee80211_rts(struct vnt_private *priv,
@@ -632,7 +560,7 @@ static int vnt_fill_ieee80211_rts(struct vnt_private *priv,
        return 0;
 }
 
-static int vnt_rxtx_rts_g_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_g_head(struct vnt_private *priv,
        struct vnt_rts_g *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -653,10 +581,11 @@ static int vnt_rxtx_rts_g_head(struct vnt_private *priv,
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration_aa);
 
-       return 0;
+       return vnt_rxtx_datahead_g(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static int vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
        struct vnt_rts_g_fb *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -678,20 +607,21 @@ static int vnt_rxtx_rts_g_fb_head(struct vnt_private *priv,
 
 
        buf->wRTSDuration_ba_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_BA_F0,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
        buf->wRTSDuration_aa_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F0,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
        buf->wRTSDuration_ba_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_BA_F1,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
        buf->wRTSDuration_aa_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration_aa);
 
-       return 0;
+       return vnt_rxtx_datahead_g_fb(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static int vnt_rxtx_rts_ab_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_ab_head(struct vnt_private *priv,
        struct vnt_rts_ab *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -706,10 +636,11 @@ static int vnt_rxtx_rts_ab_head(struct vnt_private *priv,
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration);
 
-       return 0;
+       return vnt_rxtx_datahead_ab(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static int vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
+static u16 vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
        struct vnt_rts_a_fb *buf, struct ethhdr *eth_hdr,
        u8 pkt_type, u32 frame_len, int need_ack,
        u16 current_rate, u8 fb_option)
@@ -723,23 +654,24 @@ static int vnt_rxtx_rts_a_fb_head(struct vnt_private *priv,
                pkt_type, current_rate, need_ack, fb_option);
 
        buf->wRTSDuration_f0 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F0,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb0, need_ack, fb_option);
 
        buf->wRTSDuration_f1 = s_uGetRTSCTSDuration(priv, RTSDUR_AA_F1,
-               frame_len, pkt_type, current_rate, need_ack, fb_option);
+               frame_len, pkt_type, priv->tx_rate_fb1, need_ack, fb_option);
 
        vnt_fill_ieee80211_rts(priv, &buf->data, eth_hdr, buf->wDuration);
 
-       return 0;
+       return vnt_rxtx_datahead_a_fb(priv, pkt_type, current_rate,
+                       &buf->data_head, frame_len, need_ack);
 }
 
-static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
+static u16 s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
        union vnt_tx_data_head *head, u32 cbFrameLength, int bNeedAck,
        struct ethhdr *psEthHeader, u16 wCurrentRate, u8 byFBOption)
 {
 
        if (!head)
-               return;
+               return 0;
 
        /* Note: So far RTSHead doesn't appear in ATIM
        *       & Beacom DMA, so we don't need to take them
@@ -750,36 +682,38 @@ static void s_vFillRTSHead(struct vnt_private *pDevice, u8 byPktType,
        case PK_TYPE_11GB:
        case PK_TYPE_11GA:
                if (byFBOption == AUTO_FB_NONE)
-                       vnt_rxtx_rts_g_head(pDevice, &head->rts_g,
+                       return vnt_rxtx_rts_g_head(pDevice, &head->rts_g,
                                psEthHeader, byPktType, cbFrameLength,
                                bNeedAck, wCurrentRate, byFBOption);
                else
-                       vnt_rxtx_rts_g_fb_head(pDevice, &head->rts_g_fb,
+                       return vnt_rxtx_rts_g_fb_head(pDevice, &head->rts_g_fb,
                                psEthHeader, byPktType, cbFrameLength,
                                bNeedAck, wCurrentRate, byFBOption);
                break;
        case PK_TYPE_11A:
                if (byFBOption) {
-                       vnt_rxtx_rts_a_fb_head(pDevice, &head->rts_a_fb,
+                       return vnt_rxtx_rts_a_fb_head(pDevice, &head->rts_a_fb,
                                psEthHeader, byPktType, cbFrameLength,
                                bNeedAck, wCurrentRate, byFBOption);
                        break;
                }
        case PK_TYPE_11B:
-               vnt_rxtx_rts_ab_head(pDevice, &head->rts_ab,
+               return vnt_rxtx_rts_ab_head(pDevice, &head->rts_ab,
                        psEthHeader, byPktType, cbFrameLength,
                        bNeedAck, wCurrentRate, byFBOption);
        }
+
+       return 0;
 }
 
-static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
+static u16 s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
        u8 byPktType, union vnt_tx_data_head *head, u32 cbFrameLength,
        int bNeedAck, u16 wCurrentRate, u8 byFBOption)
 {
        u32 uCTSFrameLen = 14;
 
        if (!head)
-               return;
+               return 0;
 
        if (byFBOption != AUTO_FB_NONE) {
                /* Auto Fall back */
@@ -792,16 +726,19 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
                        wCurrentRate, bNeedAck, byFBOption);
                /* Get CTSDuration_ba_f0 */
                pBuf->wCTSDuration_ba_f0 = s_uGetRTSCTSDuration(pDevice,
-                       CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate,
-                       bNeedAck, byFBOption);
+                       CTSDUR_BA_F0, cbFrameLength, byPktType,
+                       pDevice->tx_rate_fb0, bNeedAck, byFBOption);
                /* Get CTSDuration_ba_f1 */
                pBuf->wCTSDuration_ba_f1 = s_uGetRTSCTSDuration(pDevice,
-                       CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate,
-                       bNeedAck, byFBOption);
+                       CTSDUR_BA_F1, cbFrameLength, byPktType,
+                       pDevice->tx_rate_fb1, bNeedAck, byFBOption);
                /* Get CTS Frame body */
                pBuf->data.duration = pBuf->wDuration_ba;
                pBuf->data.frame_control = TYPE_CTL_CTS;
                memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
+
+               return vnt_rxtx_datahead_g_fb(pDevice, byPktType, wCurrentRate,
+                               &pBuf->data_head, cbFrameLength, bNeedAck);
        } else {
                struct vnt_cts *pBuf = &head->cts_g;
                /* Get SignalField,ServiceField,Length */
@@ -815,7 +752,12 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
                pBuf->data.duration = pBuf->wDuration_ba;
                pBuf->data.frame_control = TYPE_CTL_CTS;
                memcpy(pBuf->data.ra, pDevice->abyCurrentNetAddr, ETH_ALEN);
+
+               return vnt_rxtx_datahead_g(pDevice, byPktType, wCurrentRate,
+                               &pBuf->data_head, cbFrameLength, bNeedAck);
         }
+
+       return 0;
 }
 
 /*+
@@ -841,112 +783,160 @@ static void s_vFillCTSHead(struct vnt_private *pDevice, u32 uDMAIdx,
  *
 -*/
 
-static void s_vGenerateTxParameter(struct vnt_private *pDevice,
-       u8 byPktType, u16 wCurrentRate, void *pTxBufHead, void *pvRrvTime,
-       void *rts_cts, u32 cbFrameSize, int bNeedACK, u32 uDMAIdx,
-       struct ethhdr *psEthHeader, bool need_rts)
+static u16 s_vGenerateTxParameter(struct vnt_private *pDevice,
+       u8 byPktType, u16 wCurrentRate, struct vnt_tx_buffer *tx_buffer,
+       struct vnt_mic_hdr **mic_hdr, u32 need_mic, u32 cbFrameSize,
+       int bNeedACK, u32 uDMAIdx, struct ethhdr *psEthHeader, bool need_rts)
 {
-       union vnt_tx_data_head *head = rts_cts;
+       struct vnt_tx_fifo_head *pFifoHead = &tx_buffer->fifo_head;
+       union vnt_tx_data_head *head = NULL;
        u32 cbMACHdLen = WLAN_HDR_ADDR3_LEN; /* 24 */
        u16 wFifoCtl;
        u8 byFBOption = AUTO_FB_NONE;
 
-    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
-    PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
-    pFifoHead->wReserved = wCurrentRate;
-    wFifoCtl = pFifoHead->wFIFOCtl;
+       pFifoHead->wReserved = wCurrentRate;
+       wFifoCtl = pFifoHead->wFIFOCtl;
 
-    if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
-        byFBOption = AUTO_FB_0;
-    }
-    else if (wFifoCtl & FIFOCTL_AUTO_FB_1) {
-        byFBOption = AUTO_FB_1;
-    }
+       if (wFifoCtl & FIFOCTL_AUTO_FB_0)
+               byFBOption = AUTO_FB_0;
+       else if (wFifoCtl & FIFOCTL_AUTO_FB_1)
+               byFBOption = AUTO_FB_1;
 
-       if (!pvRrvTime)
-               return;
+       if (!pFifoHead)
+               return 0;
 
-    if (pDevice->bLongHeader)
-        cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
+       if (pDevice->bLongHeader)
+               cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
 
-    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-       if (need_rts) {
-            //Fill RsvTime
-               struct vnt_rrv_time_rts *pBuf =
-                       (struct vnt_rrv_time_rts *)pvRrvTime;
-               pBuf->wRTSTxRrvTime_aa = s_uGetRTSCTSRsvTime(pDevice, 2,
-                               byPktType, cbFrameSize, wCurrentRate);
-               pBuf->wRTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 1,
-                               byPktType, cbFrameSize, wCurrentRate);
-               pBuf->wRTSTxRrvTime_bb = s_uGetRTSCTSRsvTime(pDevice, 0,
-                               byPktType, cbFrameSize, wCurrentRate);
-               pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice,
-                       byPktType, cbFrameSize, wCurrentRate, bNeedACK);
-               pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
-                       PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate,
-                               bNeedACK);
-               /* Fill RTS */
-               s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
-                       bNeedACK, psEthHeader, wCurrentRate, byFBOption);
-        }
-        else {//RTS_needless, PCF mode
-            //Fill RsvTime
-               struct vnt_rrv_time_cts *pBuf =
-                               (struct vnt_rrv_time_cts *)pvRrvTime;
-               pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice, byPktType,
-                       cbFrameSize, wCurrentRate, bNeedACK);
-               pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
-                       PK_TYPE_11B, cbFrameSize,
-                       pDevice->byTopCCKBasicRate, bNeedACK);
-               pBuf->wCTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 3,
+       if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+               if (need_rts) {
+                       struct vnt_rrv_time_rts *pBuf =
+                                       &tx_buffer->tx_head.tx_rts.rts;
+
+                       pBuf->wRTSTxRrvTime_aa = s_uGetRTSCTSRsvTime(pDevice, 2,
+                                       byPktType, cbFrameSize, wCurrentRate);
+                       pBuf->wRTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 1,
+                                       byPktType, cbFrameSize, wCurrentRate);
+                       pBuf->wRTSTxRrvTime_bb = s_uGetRTSCTSRsvTime(pDevice, 0,
                                byPktType, cbFrameSize, wCurrentRate);
-               /* Fill CTS */
-               s_vFillCTSHead(pDevice, uDMAIdx, byPktType, head,
-                       cbFrameSize, bNeedACK, wCurrentRate, byFBOption);
-        }
-    }
-    else if (byPktType == PK_TYPE_11A) {
-       if (need_rts) {
-            //Fill RsvTime
-               struct vnt_rrv_time_ab *pBuf =
-                               (struct vnt_rrv_time_ab *)pvRrvTime;
-               pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 2,
+
+                       pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice,
+                               byPktType, cbFrameSize, wCurrentRate, bNeedACK);
+                       pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
+                                       PK_TYPE_11B, cbFrameSize,
+                                       pDevice->byTopCCKBasicRate, bNeedACK);
+
+                       if (need_mic) {
+                               *mic_hdr = &tx_buffer->
+                                               tx_head.tx_rts.tx.mic.hdr;
+                               head = &tx_buffer->tx_head.tx_rts.tx.mic.head;
+                       } else {
+                               head = &tx_buffer->tx_head.tx_rts.tx.head;
+                       }
+
+                       /* Fill RTS */
+                       return s_vFillRTSHead(pDevice, byPktType, head,
+                                       cbFrameSize, bNeedACK, psEthHeader,
+                                               wCurrentRate, byFBOption);
+
+               } else {
+                       struct vnt_rrv_time_cts *pBuf = &tx_buffer->
+                                                       tx_head.tx_cts.cts;
+
+                       pBuf->wTxRrvTime_a = vnt_rxtx_rsvtime_le16(pDevice,
+                               byPktType, cbFrameSize, wCurrentRate, bNeedACK);
+                       pBuf->wTxRrvTime_b = vnt_rxtx_rsvtime_le16(pDevice,
+                               PK_TYPE_11B, cbFrameSize,
+                                       pDevice->byTopCCKBasicRate, bNeedACK);
+
+                       pBuf->wCTSTxRrvTime_ba = s_uGetRTSCTSRsvTime(pDevice, 3,
+                                       byPktType, cbFrameSize, wCurrentRate);
+
+                       if (need_mic) {
+                               *mic_hdr = &tx_buffer->
+                                               tx_head.tx_cts.tx.mic.hdr;
+                               head = &tx_buffer->tx_head.tx_cts.tx.mic.head;
+                       } else {
+                               head = &tx_buffer->tx_head.tx_cts.tx.head;
+                       }
+
+                       /* Fill CTS */
+                       return s_vFillCTSHead(pDevice, uDMAIdx, byPktType,
+                               head, cbFrameSize, bNeedACK, wCurrentRate,
+                                       byFBOption);
+               }
+       } else if (byPktType == PK_TYPE_11A) {
+               if (need_mic) {
+                       *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
+                       head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
+               } else {
+                       head = &tx_buffer->tx_head.tx_ab.tx.head;
+               }
+
+               if (need_rts) {
+                       struct vnt_rrv_time_ab *pBuf = &tx_buffer->
+                                                       tx_head.tx_ab.ab;
+
+                       pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 2,
                                byPktType, cbFrameSize, wCurrentRate);
-               pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, byPktType,
-                               cbFrameSize, wCurrentRate, bNeedACK);
-               /* Fill RTS */
-               s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
-                       bNeedACK, psEthHeader, wCurrentRate, byFBOption);
-       } else {
-            //Fill RsvTime
-               struct vnt_rrv_time_ab *pBuf =
-                               (struct vnt_rrv_time_ab *)pvRrvTime;
-               pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11A,
-                       cbFrameSize, wCurrentRate, bNeedACK);
-        }
-    }
-    else if (byPktType == PK_TYPE_11B) {
-       if (need_rts) {
-            //Fill RsvTime
-               struct vnt_rrv_time_ab *pBuf =
-                               (struct vnt_rrv_time_ab *)pvRrvTime;
-               pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 0,
+
+                       pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
+                               byPktType, cbFrameSize, wCurrentRate, bNeedACK);
+
+                       /* Fill RTS */
+                       return s_vFillRTSHead(pDevice, byPktType, head,
+                               cbFrameSize, bNeedACK, psEthHeader,
+                                       wCurrentRate, byFBOption);
+               } else {
+                       struct vnt_rrv_time_ab *pBuf = &tx_buffer->
+                                                       tx_head.tx_ab.ab;
+
+                       pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
+                               PK_TYPE_11A, cbFrameSize,
+                                       wCurrentRate, bNeedACK);
+
+                       return vnt_rxtx_datahead_a_fb(pDevice, byPktType,
+                               wCurrentRate, &head->data_head_a_fb,
+                                               cbFrameSize, bNeedACK);
+               }
+       } else if (byPktType == PK_TYPE_11B) {
+               if (need_mic) {
+                       *mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr;
+                       head = &tx_buffer->tx_head.tx_ab.tx.mic.head;
+               } else {
+                       head = &tx_buffer->tx_head.tx_ab.tx.head;
+               }
+
+               if (need_rts) {
+                       struct vnt_rrv_time_ab *pBuf = &tx_buffer->
+                                                       tx_head.tx_ab.ab;
+
+                       pBuf->wRTSTxRrvTime = s_uGetRTSCTSRsvTime(pDevice, 0,
                                byPktType, cbFrameSize, wCurrentRate);
-               pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B,
-                               cbFrameSize, wCurrentRate, bNeedACK);
-               /* Fill RTS */
-               s_vFillRTSHead(pDevice, byPktType, head, cbFrameSize,
+
+                       pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
+                               PK_TYPE_11B, cbFrameSize, wCurrentRate,
+                                                               bNeedACK);
+
+                       /* Fill RTS */
+                       return s_vFillRTSHead(pDevice, byPktType, head,
+                               cbFrameSize,
                        bNeedACK, psEthHeader, wCurrentRate, byFBOption);
-        }
-        else { //RTS_needless, non PCF mode
-            //Fill RsvTime
-               struct vnt_rrv_time_ab *pBuf =
-                               (struct vnt_rrv_time_ab *)pvRrvTime;
-               pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice, PK_TYPE_11B,
-                       cbFrameSize, wCurrentRate, bNeedACK);
-        }
-    }
-    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
+               } else {
+                       struct vnt_rrv_time_ab *pBuf = &tx_buffer->
+                                                       tx_head.tx_ab.ab;
+
+                       pBuf->wTxRrvTime = vnt_rxtx_rsvtime_le16(pDevice,
+                               PK_TYPE_11B, cbFrameSize,
+                                       wCurrentRate, bNeedACK);
+
+                       return vnt_rxtx_datahead_ab(pDevice, byPktType,
+                               wCurrentRate, &head->data_head_ab,
+                                       cbFrameSize, bNeedACK);
+               }
+       }
+
+       return 0;
 }
 /*
     u8 * pbyBuffer,//point to pTxBufHead
@@ -955,11 +945,12 @@ static void s_vGenerateTxParameter(struct vnt_private *pDevice,
 */
 
 static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
-       struct vnt_tx_buffer *pTxBufHead, int bNeedEncryption,
+       struct vnt_tx_buffer *tx_buffer, int bNeedEncryption,
        u32 uSkbPacketLen, u32 uDMAIdx, struct ethhdr *psEthHeader,
        u8 *pPacket, PSKeyItem pTransmitKey, u32 uNodeIndex, u16 wCurrentRate,
        u32 *pcbHeaderLen, u32 *pcbTotalLen)
 {
+       struct vnt_tx_fifo_head *pTxBufHead = &tx_buffer->fifo_head;
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        u32 cbFrameSize, cbFrameBodySize;
        u32 cb802_1_H_len;
@@ -973,17 +964,14 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
                = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
        u32 uDuration;
        u32 cbHeaderLength = 0, uPadding = 0;
-       void *pvRrvTime;
        struct vnt_mic_hdr *pMICHDR;
-       void *rts_cts = NULL;
-       void *pvTxDataHd;
        u8 byFBOption = AUTO_FB_NONE, byFragType;
        u16 wTxBufSize;
        u32 dwMICKey0, dwMICKey1, dwMIC_Priority;
        u32 *pdwMIC_L, *pdwMIC_R;
        int bSoftWEP = false;
 
-       pvRrvTime = pMICHDR = pvTxDataHd = NULL;
+       pMICHDR = NULL;
 
        if (bNeedEncryption && pTransmitKey->pvKeyTable) {
                if (((PSKeyTable)pTransmitKey->pvKeyTable)->bSoftWEP == true)
@@ -1047,16 +1035,27 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
         pTxBufHead->wFIFOCtl |=        FIFOCTL_GRPACK;
     }
 
-    //Set Auto Fallback Ctl
-    if (wCurrentRate >= RATE_18M) {
-        if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
-            pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
-            byFBOption = AUTO_FB_0;
-        } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
-            pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
-            byFBOption = AUTO_FB_1;
-        }
-    }
+       /* Set Auto Fallback Ctl */
+       if (wCurrentRate >= RATE_18M) {
+               if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
+                       pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
+
+                       pDevice->tx_rate_fb0 =
+                               wFB_Opt0[FB_RATE0][wCurrentRate - RATE_18M];
+                       pDevice->tx_rate_fb1 =
+                               wFB_Opt0[FB_RATE1][wCurrentRate - RATE_18M];
+
+                       byFBOption = AUTO_FB_0;
+               } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
+                       pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
+                       pDevice->tx_rate_fb0 =
+                               wFB_Opt1[FB_RATE0][wCurrentRate - RATE_18M];
+                       pDevice->tx_rate_fb1 =
+                               wFB_Opt1[FB_RATE1][wCurrentRate - RATE_18M];
+
+                       byFBOption = AUTO_FB_1;
+               }
+       }
 
     if (bSoftWEP != true) {
         if ((bNeedEncryption) && (pTransmitKey != NULL))  { //WEP enabled
@@ -1105,118 +1104,47 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
     }
 
     pbyTxBufferAddr = (u8 *) &(pTxBufHead->adwTxKey[0]);
-    wTxBufSize = sizeof(STxBufHead);
+       wTxBufSize = sizeof(struct vnt_tx_fifo_head);
+
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
         if (byFBOption == AUTO_FB_NONE) {
             if (bRTS == true) {//RTS_need
-               pvRrvTime = (struct vnt_rrv_time_rts *)
-                                       (pbyTxBufferAddr + wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize +
-                                       sizeof(struct vnt_rrv_time_rts));
-               rts_cts = (struct vnt_rts_g *) (pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_g *) (pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                               cbMICHDR + sizeof(struct vnt_rts_g));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                       cbMICHDR + sizeof(struct vnt_rts_g) +
-                               sizeof(struct vnt_tx_datahead_g);
+                       cbMICHDR + sizeof(struct vnt_rts_g);
             }
             else { //RTS_needless
-               pvRrvTime = (struct vnt_rrv_time_cts *)
-                               (pbyTxBufferAddr + wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                       sizeof(struct vnt_rrv_time_cts));
-               rts_cts = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_g *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                               cbMICHDR + sizeof(struct vnt_cts));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                       cbMICHDR + sizeof(struct vnt_cts) +
-                               sizeof(struct vnt_tx_datahead_g);
+                       cbMICHDR + sizeof(struct vnt_cts);
             }
         } else {
             // Auto Fall Back
             if (bRTS == true) {//RTS_need
-               pvRrvTime = (struct vnt_rrv_time_rts *)(pbyTxBufferAddr +
-                                                               wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                                       sizeof(struct vnt_rrv_time_rts));
-               rts_cts = (struct vnt_rts_g_fb *)(pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_rts) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_g_fb *) (pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                               cbMICHDR + sizeof(struct vnt_rts_g_fb));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_rts) +
-                       cbMICHDR + sizeof(struct vnt_rts_g_fb) +
-                               sizeof(struct vnt_tx_datahead_g_fb);
+                       cbMICHDR + sizeof(struct vnt_rts_g_fb);
             }
             else if (bRTS == false) { //RTS_needless
-               pvRrvTime = (struct vnt_rrv_time_cts *)
-                               (pbyTxBufferAddr + wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_cts));
-               rts_cts = (struct vnt_cts_fb *) (pbyTxBufferAddr + wTxBufSize +
-                       sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_g_fb *) (pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                               cbMICHDR + sizeof(struct vnt_cts_fb));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-                               cbMICHDR + sizeof(struct vnt_cts_fb) +
-                                       sizeof(struct vnt_tx_datahead_g_fb);
+                               cbMICHDR + sizeof(struct vnt_cts_fb);
             }
         } // Auto Fall Back
     }
     else {//802.11a/b packet
         if (byFBOption == AUTO_FB_NONE) {
             if (bRTS == true) {//RTS_need
-               pvRrvTime = (struct vnt_rrv_time_ab *) (pbyTxBufferAddr +
-                                                               wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize +
-                                               sizeof(struct vnt_rrv_time_ab));
-               rts_cts = (struct vnt_rts_ab *) (pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
-                                               sizeof(struct vnt_rts_ab));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
-                       cbMICHDR + sizeof(struct vnt_rts_ab) +
-                               sizeof(struct vnt_tx_datahead_ab);
+                       cbMICHDR + sizeof(struct vnt_rts_ab);
             }
             else if (bRTS == false) { //RTS_needless, no MICHDR
-               pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
-                                                               wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                                               sizeof(struct vnt_rrv_time_ab));
-               pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
                                cbMICHDR + sizeof(struct vnt_tx_datahead_ab);
             }
         } else {
             // Auto Fall Back
             if (bRTS == true) {//RTS_need
-               pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
-                                               wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                       sizeof(struct vnt_rrv_time_ab));
-               rts_cts = (struct vnt_rts_a_fb *)(pbyTxBufferAddr + wTxBufSize +
-                               sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
-               pvTxDataHd = (struct vnt_tx_datahead_a_fb *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
-                                       sizeof(struct vnt_rts_a_fb));
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
-                       cbMICHDR + sizeof(struct vnt_rts_a_fb) +
-                                       sizeof(struct vnt_tx_datahead_a_fb);
+                       cbMICHDR + sizeof(struct vnt_rts_a_fb);
             }
             else if (bRTS == false) { //RTS_needless
-               pvRrvTime = (struct vnt_rrv_time_ab *)(pbyTxBufferAddr +
-                                                               wTxBufSize);
-               pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize +
-                                               sizeof(struct vnt_rrv_time_ab));
-               pvTxDataHd = (struct vnt_tx_datahead_a_fb *)(pbyTxBufferAddr +
-                       wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
                cbHeaderLength = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
                        cbMICHDR + sizeof(struct vnt_tx_datahead_a_fb);
             }
@@ -1235,20 +1163,18 @@ static int s_bPacketToWirelessUsb(struct vnt_private *pDevice, u8 byPktType,
     //uDMAIdx = TYPE_AC0DMA;
     //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
 
-    //Fill FIFO,RrvTime,RTS,and CTS
-    s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
-               (void *)pbyTxBufferAddr, pvRrvTime, rts_cts,
-               cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, bRTS);
-    //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
-                               byFBOption);
+       /* Fill FIFO, RrvTime, RTS and CTS */
+       uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
+                       tx_buffer, &pMICHDR, cbMICHDR,
+                       cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, bRTS);
+
     // Generate TX MAC Header
     s_vGenerateMACHeader(pDevice, pbyMacHdr, (u16)uDuration, psEthHeader, bNeedEncryption,
                            byFragType, uDMAIdx, 0);
 
     if (bNeedEncryption == true) {
         //Fill TXKEY
-        s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+       s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
                pbyMacHdr, (u16)cbFrameBodySize, pMICHDR);
 
         if (pDevice->bEnableHostWEP) {
@@ -1469,13 +1395,12 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
 {
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        struct vnt_tx_buffer *pTX_Buffer;
-       PSTxBufHead pTxBufHead;
        struct vnt_usb_send_context *pContext;
+       struct vnt_tx_fifo_head *pTxBufHead;
        struct ieee80211_hdr *pMACHeader;
        struct ethhdr sEthHeader;
        u8 byPktType, *pbyTxBufferAddr;
-       void *rts_cts = NULL;
-       void *pvTxDataHd, *pvRrvTime, *pMICHDR;
+       struct vnt_mic_hdr *pMICHDR = NULL;
        u32 uDuration, cbReqCount, cbHeaderSize, cbFrameBodySize, cbFrameSize;
        int bNeedACK, bIsPSPOLL = false;
        u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
@@ -1492,10 +1417,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
     }
 
        pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
-    pbyTxBufferAddr = (u8 *)&(pTX_Buffer->adwTxKey[0]);
     cbFrameBodySize = pPacket->cbPayloadLen;
-    pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
-    wTxBufSize = sizeof(STxBufHead);
+       pTxBufHead = &pTX_Buffer->fifo_head;
+       pbyTxBufferAddr = (u8 *)&pTxBufHead->adwTxKey[0];
+       wTxBufSize = sizeof(struct vnt_tx_fifo_head);
 
     if (pDevice->byBBType == BB_TYPE_11A) {
         wCurrentRate = RATE_6M;
@@ -1607,21 +1532,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
 
     //Set RrvTime/RTS/CTS Buffer
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
-
-       pvRrvTime = (struct vnt_rrv_time_cts *) (pbyTxBufferAddr + wTxBufSize);
-        pMICHDR = NULL;
-       rts_cts = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
-                                       sizeof(struct vnt_rrv_time_cts));
-       pvTxDataHd = (struct vnt_tx_datahead_g *)(pbyTxBufferAddr + wTxBufSize +
-               sizeof(struct vnt_rrv_time_cts) + sizeof(struct vnt_cts));
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) +
-               sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
+               sizeof(struct vnt_cts);
     }
     else { // 802.11a/b packet
-       pvRrvTime = (struct vnt_rrv_time_ab *) (pbyTxBufferAddr + wTxBufSize);
-        pMICHDR = NULL;
-       pvTxDataHd = (struct vnt_tx_datahead_ab *) (pbyTxBufferAddr +
-               wTxBufSize + sizeof(struct vnt_rrv_time_ab));
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) +
                sizeof(struct vnt_tx_datahead_ab);
     }
@@ -1638,14 +1552,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
     pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
 
        /* Fill FIFO,RrvTime,RTS,and CTS */
-       s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
-               pbyTxBufferAddr, pvRrvTime, rts_cts,
+       uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
+               pTX_Buffer, &pMICHDR, 0,
                cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, false);
 
-    //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
-                               AUTO_FB_NONE);
-
     pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
 
     cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
@@ -1684,7 +1594,7 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
             }
         } while(false);
         //Fill TXKEY
-        s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+       s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
                      (u8 *)pMACHeader, (u16)cbFrameBodySize, NULL);
 
         memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
@@ -1708,12 +1618,16 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
         // in the same place of other packet's Duration-field).
         // And it will cause Cisco-AP to issue Disassociation-packet
        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_a =
+               struct vnt_tx_datahead_g *data_head = &pTX_Buffer->tx_head.
+                                               tx_cts.tx.head.cts_g.data_head;
+               data_head->wDuration_a =
                        cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
+               data_head->wDuration_b =
                        cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
        } else {
-               ((struct vnt_tx_datahead_ab *)pvTxDataHd)->wDuration =
+               struct vnt_tx_datahead_ab *data_head = &pTX_Buffer->tx_head.
+                                       tx_ab.tx.head.data_head_ab;
+               data_head->wDuration =
                        cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
        }
     }
@@ -1727,10 +1641,14 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice,
     pContext->uBufLen = (u16)cbReqCount + 4;  //USB header
 
     if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
-        s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+       s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+                       &pMACHeader->addr1[0], (u16)cbFrameSize,
+                       pTxBufHead->wFIFOCtl);
     }
     else {
-        s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+       s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+                       &pMACHeader->addr3[0], (u16)cbFrameSize,
+                       pTxBufHead->wFIFOCtl);
     }
 
     PIPEnsSendBulkOut(pDevice,pContext);
@@ -1825,15 +1743,13 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
 {
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        struct vnt_tx_buffer *pTX_Buffer;
+       struct vnt_tx_fifo_head *pTxBufHead;
        u8 byPktType;
        u8 *pbyTxBufferAddr;
-       void *rts_cts = NULL;
-       void *pvTxDataHd;
        u32 uDuration, cbReqCount;
        struct ieee80211_hdr *pMACHeader;
        u32 cbHeaderSize, cbFrameBodySize;
        int bNeedACK, bIsPSPOLL = false;
-       PSTxBufHead pTxBufHead;
        u32 cbFrameSize;
        u32 cbIVlen = 0, cbICVlen = 0, cbMIClen = 0, cbFCSlen = 4;
        u32 uPadding = 0;
@@ -1844,7 +1760,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
        u16 wTxBufSize;
        u32 cbMacHdLen;
        struct ethhdr sEthHeader;
-       void *pvRrvTime, *pMICHDR;
+       struct vnt_mic_hdr *pMICHDR;
        u32 wCurrentRate = RATE_1M;
        PUWLAN_80211HDR  p80211Header;
        u32 uNodeIndex = 0;
@@ -1855,7 +1771,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
        u32 cbExtSuppRate = 0;
        struct vnt_usb_send_context *pContext;
 
-       pvRrvTime = pMICHDR = pvTxDataHd = NULL;
+       pMICHDR = NULL;
 
     if(skb->len <= WLAN_HDR_ADDR3_LEN) {
        cbFrameBodySize = 0;
@@ -1874,9 +1790,9 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     }
 
        pTX_Buffer = (struct vnt_tx_buffer *)&pContext->Data[0];
-    pbyTxBufferAddr = (u8 *)(&pTX_Buffer->adwTxKey[0]);
-    pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
-    wTxBufSize = sizeof(STxBufHead);
+       pTxBufHead = &pTX_Buffer->fifo_head;
+       pbyTxBufferAddr = (u8 *)&pTxBufHead->adwTxKey[0];
+       wTxBufSize = sizeof(struct vnt_tx_fifo_head);
 
     if (pDevice->byBBType == BB_TYPE_11A) {
         wCurrentRate = RATE_6M;
@@ -2014,25 +1930,11 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
 
     if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
-       pvRrvTime = (struct vnt_rrv_time_cts *) (pbyTxBufferAddr + wTxBufSize);
-       pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-                                       sizeof(struct vnt_rrv_time_cts));
-       rts_cts = (struct vnt_cts *) (pbyTxBufferAddr + wTxBufSize +
-                       sizeof(struct vnt_rrv_time_cts) + cbMICHDR);
-       pvTxDataHd = (struct vnt_tx_datahead_g *) (pbyTxBufferAddr +
-               wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
-                                       sizeof(struct vnt_cts));
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_cts) + cbMICHDR +
-               sizeof(struct vnt_cts) + sizeof(struct vnt_tx_datahead_g);
+               sizeof(struct vnt_cts);
 
     }
     else {//802.11a/b packet
-
-       pvRrvTime = (struct vnt_rrv_time_ab *) (pbyTxBufferAddr + wTxBufSize);
-       pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize +
-               sizeof(struct vnt_rrv_time_ab));
-       pvTxDataHd = (struct vnt_tx_datahead_ab *)(pbyTxBufferAddr +
-               wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR);
        cbHeaderSize = wTxBufSize + sizeof(struct vnt_rrv_time_ab) + cbMICHDR +
                                        sizeof(struct vnt_tx_datahead_ab);
     }
@@ -2048,15 +1950,11 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     pTxBufHead->wFragCtl |= (u16)FRAGCTL_NONFRAG;
 
        /* Fill FIFO,RrvTime,RTS,and CTS */
-       s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
-               pbyTxBufferAddr, pvRrvTime, rts_cts,
+       uDuration = s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,
+               pTX_Buffer, &pMICHDR, cbMICHDR,
                cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, false);
 
-    //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
-                               AUTO_FB_NONE);
-
-    pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
+       pMACHeader = (struct ieee80211_hdr *) (pbyTxBufferAddr + cbHeaderSize);
 
     cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
 
@@ -2139,7 +2037,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
 
         }
 
-        s_vFillTxKey(pDevice, (u8 *)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+       s_vFillTxKey(pDevice, pTxBufHead, pbyIVHead, pTransmitKey,
                pbyMacHdr, (u16)cbFrameBodySize, pMICHDR);
 
         if (pDevice->bEnableHostWEP) {
@@ -2164,12 +2062,16 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
         // in the same place of other packet's Duration-field).
         // And it will cause Cisco-AP to issue Disassociation-packet
        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_a =
+               struct vnt_tx_datahead_g *data_head = &pTX_Buffer->tx_head.
+                                               tx_cts.tx.head.cts_g.data_head;
+               data_head->wDuration_a =
                        cpu_to_le16(p80211Header->sA2.wDurationID);
-               ((struct vnt_tx_datahead_g *)pvTxDataHd)->wDuration_b =
+               data_head->wDuration_b =
                        cpu_to_le16(p80211Header->sA2.wDurationID);
        } else {
-               ((struct vnt_tx_datahead_ab *)pvTxDataHd)->wDuration =
+               struct vnt_tx_datahead_ab *data_head = &pTX_Buffer->tx_head.
+                                       tx_ab.tx.head.data_head_ab;
+               data_head->wDuration =
                        cpu_to_le16(p80211Header->sA2.wDurationID);
        }
     }
@@ -2183,10 +2085,14 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb)
     pContext->uBufLen = (u16)cbReqCount + 4;  //USB header
 
     if (WLAN_GET_FC_TODS(pMACHeader->frame_control) == 0) {
-        s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr1[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+       s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+                       &pMACHeader->addr1[0], (u16)cbFrameSize,
+                       pTxBufHead->wFIFOCtl);
     }
     else {
-        s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->addr3[0]), (u16)cbFrameSize, pTX_Buffer->wFIFOCtl);
+       s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+                       &pMACHeader->addr3[0], (u16)cbFrameSize,
+                       pTxBufHead->wFIFOCtl);
     }
     PIPEnsSendBulkOut(pDevice,pContext);
     return ;
@@ -2568,7 +2474,10 @@ int nsDMA_tx_packet(struct vnt_private *pDevice,
     pContext->Type = CONTEXT_DATA_PACKET;
     pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
 
-    s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.h_dest[0]), (u16) (BytesToWrite-uHeaderLen), pTX_Buffer->wFIFOCtl);
+    s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+                       &pContext->sEthHeader.h_dest[0],
+                       (u16)(BytesToWrite-uHeaderLen),
+                       pTX_Buffer->fifo_head.wFIFOCtl);
 
     status = PIPEnsSendBulkOut(pDevice,pContext);
 
@@ -2719,7 +2628,10 @@ int bRelayPacketSend(struct vnt_private *pDevice, u8 *pbySkbData, u32 uDataLen,
     pContext->Type = CONTEXT_DATA_PACKET;
     pContext->uBufLen = (u16)BytesToWrite + 4 ; //USB header
 
-    s_vSaveTxPktInfo(pDevice, (u8) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.h_dest[0]), (u16) (BytesToWrite-uHeaderLen), pTX_Buffer->wFIFOCtl);
+    s_vSaveTxPktInfo(pDevice, (u8)(pTX_Buffer->byPKTNO & 0x0F),
+               &pContext->sEthHeader.h_dest[0],
+               (u16)(BytesToWrite - uHeaderLen),
+               pTX_Buffer->fifo_head.wFIFOCtl);
 
     status = PIPEnsSendBulkOut(pDevice,pContext);
 
index 4bbee1c2fcacef62a866c7b222605210ee2674ec..eecbe890027e50976461925022ac87e8dac9dfc8 100644 (file)
@@ -117,6 +117,7 @@ struct vnt_rts_g {
        u16 wDuration_bb;
        u16 wReserved;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_g data_head;
 } __packed;
 
 struct vnt_rts_g_fb {
@@ -131,6 +132,7 @@ struct vnt_rts_g_fb {
        u16 wRTSDuration_ba_f1;
        u16 wRTSDuration_aa_f1;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_g_fb data_head;
 } __packed;
 
 struct vnt_rts_ab {
@@ -138,6 +140,7 @@ struct vnt_rts_ab {
        u16 wDuration;
        u16 wReserved;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_ab data_head;
 } __packed;
 
 struct vnt_rts_a_fb {
@@ -147,6 +150,7 @@ struct vnt_rts_a_fb {
        u16 wRTSDuration_f0;
        u16 wRTSDuration_f1;
        struct ieee80211_rts data;
+       struct vnt_tx_datahead_a_fb data_head;
 } __packed;
 
 /* CTS buffer header */
@@ -156,6 +160,7 @@ struct vnt_cts {
        u16 wReserved;
        struct ieee80211_cts data;
        u16 reserved2;
+       struct vnt_tx_datahead_g data_head;
 } __packed;
 
 struct vnt_cts_fb {
@@ -166,6 +171,7 @@ struct vnt_cts_fb {
        u16 wCTSDuration_ba_f1;
        struct ieee80211_cts data;
        u16 reserved2;
+       struct vnt_tx_datahead_g_fb data_head;
 } __packed;
 
 union vnt_tx_data_head {
@@ -178,12 +184,37 @@ union vnt_tx_data_head {
        /* cts g */
        struct vnt_cts cts_g;
        struct vnt_cts_fb cts_g_fb;
+       /* no rts/cts */
+       struct vnt_tx_datahead_a_fb data_head_a_fb;
+       struct vnt_tx_datahead_ab data_head_ab;
 };
 
-struct vnt_tx_buffer {
-       u8 byType;
-       u8 byPKTNO;
-       u16 wTxByteCount;
+struct vnt_tx_mic_hdr {
+       struct vnt_mic_hdr hdr;
+       union vnt_tx_data_head head;
+} __packed;
+
+union vnt_tx {
+       struct vnt_tx_mic_hdr mic;
+       union vnt_tx_data_head head;
+};
+
+union vnt_tx_head {
+       struct {
+               struct vnt_rrv_time_rts rts;
+               union vnt_tx tx;
+       } __packed tx_rts;
+       struct {
+               struct vnt_rrv_time_cts cts;
+               union vnt_tx tx;
+       } __packed tx_cts;
+       struct {
+               struct vnt_rrv_time_ab ab;
+               union vnt_tx tx;
+       } __packed tx_ab;
+};
+
+struct vnt_tx_fifo_head {
        u32 adwTxKey[4];
        u16 wFIFOCtl;
        u16 wTimeStamp;
@@ -191,6 +222,14 @@ struct vnt_tx_buffer {
        u16 wReserved;
 } __packed;
 
+struct vnt_tx_buffer {
+       u8 byType;
+       u8 byPKTNO;
+       u16 wTxByteCount;
+       struct vnt_tx_fifo_head fifo_head;
+       union vnt_tx_head tx_head;
+} __packed;
+
 struct vnt_beacon_buffer {
        u8 byType;
        u8 byPKTNO;
index 3a03f1d5b6856c3c948b33253dfc4e06d5f2928a..5fc18ad822d3046f65cf4205c4484dccbf85e16b 100644 (file)
@@ -118,6 +118,9 @@ int PIPEnsControlOut(struct vnt_private *pDevice, u8 byRequest, u16 wValue,
        if (pDevice->Flags & fMP_CONTROL_READS)
                return STATUS_FAILURE;
 
+       if (pDevice->pControlURB->hcpriv)
+               return STATUS_FAILURE;
+
        MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES);
 
        pDevice->sUsbCtlRequest.bRequestType = 0x40;
@@ -177,6 +180,9 @@ int PIPEnsControlIn(struct vnt_private *pDevice, u8 byRequest, u16 wValue,
        if (pDevice->Flags & fMP_CONTROL_WRITES)
                return STATUS_FAILURE;
 
+       if (pDevice->pControlURB->hcpriv)
+               return STATUS_FAILURE;
+
        MP_SET_FLAG(pDevice, fMP_CONTROL_READS);
 
        pDevice->sUsbCtlRequest.bRequestType = 0xC0;
@@ -656,8 +662,6 @@ static void s_nsBulkOutIoCompleteWrite(struct urb *urb)
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Write %d bytes\n",(int)ulBufLen);
         pDevice->ulBulkOutBytesWrite += ulBufLen;
         pDevice->ulBulkOutContCRCError = 0;
-       pDevice->nTxDataTimeCout = 0;
-
     } else {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK Out failed %d\n", status);
         pDevice->ulBulkOutError++;
index 0013cb73d83bcc94dfdadb5e5f3c0aadfdfe9236..2f8e2a87533182a8f9bfa4fd3f62857067d8a731 100644 (file)
@@ -268,20 +268,14 @@ struct vnt_tx_mgmt *s_MgrMakeProbeRequest(struct vnt_private *pDevice,
 
 void vCommandTimerWait(struct vnt_private *pDevice, unsigned long MSecond)
 {
-
-       init_timer(&pDevice->sTimerCommand);
-
-       pDevice->sTimerCommand.data = (unsigned long)pDevice;
-       pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
-       pDevice->sTimerCommand.expires = RUN_AT((MSecond * HZ) / 1000);
-
-       add_timer(&pDevice->sTimerCommand);
-
-       return;
+       schedule_delayed_work(&pDevice->run_command_work,
+                                               msecs_to_jiffies(MSecond));
 }
 
-void vRunCommand(struct vnt_private *pDevice)
+void vRunCommand(struct work_struct *work)
 {
+       struct vnt_private *pDevice =
+               container_of(work, struct vnt_private, run_command_work.work);
        struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
        PWLAN_IE_SSID pItemSSID;
        PWLAN_IE_SSID pItemSSIDCurr;
@@ -292,6 +286,9 @@ void vRunCommand(struct vnt_private *pDevice)
        u8 byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
        u8 byData;
 
+       if (pDevice->Flags & fMP_DISCONNECTED)
+               return;
+
     if (pDevice->dwDiagRefCount != 0)
         return;
     if (pDevice->bCmdRunning != true)
@@ -660,22 +657,6 @@ void vRunCommand(struct vnt_private *pDevice)
                     netif_wake_queue(pDevice->dev);
                 }
 
-                if(pDevice->IsTxDataTrigger != false)   {    //TxDataTimer is not triggered at the first time
-                     // printk("Re-initial TxDataTimer****\n");
-                   del_timer(&pDevice->sTimerTxData);
-                      init_timer(&pDevice->sTimerTxData);
-                       pDevice->sTimerTxData.data = (unsigned long) pDevice;
-                      pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
-                      pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
-                      pDevice->fTxDataInSleep = false;
-                      pDevice->nTxDataTimeCout = 0;
-                }
-                else {
-                  // printk("mike:-->First time trigger TimerTxData InSleep\n");
-                }
-               pDevice->IsTxDataTrigger = true;
-                add_timer(&pDevice->sTimerTxData);
-
             }
           else if(pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) {
                printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
@@ -687,7 +668,6 @@ void vRunCommand(struct vnt_private *pDevice)
               vCommandTimerWait((void *) pDevice, ASSOCIATE_TIMEOUT/2);
               return;
           }
-                 pDevice->byLinkWaitCount = 0;
 
             s_bCommandComplete(pDevice);
             break;
@@ -696,7 +676,7 @@ void vRunCommand(struct vnt_private *pDevice)
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n");
 
             if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
-                del_timer(&pMgmt->sTimerSecondCallback);
+               cancel_delayed_work_sync(&pDevice->second_callback_work);
                 pMgmt->eCurrState = WMAC_STATE_IDLE;
                 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
                 pDevice->bLinkPass = false;
@@ -724,7 +704,7 @@ void vRunCommand(struct vnt_private *pDevice)
                 }
                 pDevice->bLinkPass = true;
                 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
-                add_timer(&pMgmt->sTimerSecondCallback);
+               schedule_delayed_work(&pDevice->second_callback_work, HZ);
             }
             s_bCommandComplete(pDevice);
             break;
@@ -1156,14 +1136,8 @@ static int s_bClearBSSID_SCAN(struct vnt_private *pDevice)
 //mike add:reset command timer
 void vResetCommandTimer(struct vnt_private *pDevice)
 {
+       cancel_delayed_work_sync(&pDevice->run_command_work);
 
-       //delete timer
-       del_timer(&pDevice->sTimerCommand);
-       //init timer
-       init_timer(&pDevice->sTimerCommand);
-       pDevice->sTimerCommand.data = (unsigned long)pDevice;
-       pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
-       pDevice->sTimerCommand.expires = RUN_AT(HZ);
        pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
        pDevice->uCmdDequeueIdx = 0;
        pDevice->uCmdEnqueueIdx = 0;
@@ -1171,33 +1145,3 @@ void vResetCommandTimer(struct vnt_private *pDevice)
        pDevice->bCmdRunning = false;
        pDevice->bCmdClear = false;
 }
-
-void BSSvSecondTxData(struct vnt_private *pDevice)
-{
-       struct vnt_manager *pMgmt = &pDevice->vnt_mgmt;
-
-       pDevice->nTxDataTimeCout++;
-
-       if (pDevice->nTxDataTimeCout < 4) {   //don't tx data if timer less than 40s
-               // printk("mike:%s-->no data Tx not exceed the desired Time as %d\n",__FUNCTION__,
-               //      (int)pDevice->nTxDataTimeCout);
-               pDevice->sTimerTxData.expires = RUN_AT(10 * HZ);      //10s callback
-               add_timer(&pDevice->sTimerTxData);
-               return;
-       }
-
-       spin_lock_irq(&pDevice->lock);
-       //is wap_supplicant running successful OR only open && sharekey mode!
-       if (((pDevice->bLinkPass == true) &&
-               (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
-               (pDevice->fWPA_Authened == true)) {   //wpa linking
-               //   printk("mike:%s-->InSleep Tx Data Procedure\n",__FUNCTION__);
-               pDevice->fTxDataInSleep = true;
-               PSbSendNullPacket(pDevice);      //send null packet
-               pDevice->fTxDataInSleep = false;
-       }
-       spin_unlock_irq(&pDevice->lock);
-
-       pDevice->sTimerTxData.expires = RUN_AT(10 * HZ);      //10s callback
-       add_timer(&pDevice->sTimerTxData);
-}
index db8b4cf7fd601ff4f29832658481abbb2c8c3708..caf2684ce9151f34961d5d203e4e7949c5d5b9da 100644 (file)
@@ -105,15 +105,6 @@ void vResetCommandTimer(struct vnt_private *);
 
 int bScheduleCommand(struct vnt_private *, CMD_CODE eCommand, u8 *pbyItem0);
 
-void vRunCommand(struct vnt_private *);
-
-/*
-void
-WCMDvCommandThread(
-    void * Context
-    );
-*/
-
-void BSSvSecondTxData(struct vnt_private *);
+void vRunCommand(struct work_struct *work);
 
 #endif /* __WCMD_H__ */
index 47a655db51efe7491af61f9243691e3660ea7ff4..814342cd948ed9509d175d8ece30734b05d9f69a 100644 (file)
@@ -69,8 +69,7 @@ bool WCTLbIsDuplicate (PSCache pCache, struct ieee80211_hdr *pMACHeader)
         for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) {
             pCacheEntry = &(pCache->asCacheEntry[uIndex]);
             if ((pCacheEntry->wFmSequence == pMACHeader->seq_ctrl) &&
-               (!compare_ether_addr(&(pCacheEntry->abyAddr2[0]),
-                                    &(pMACHeader->addr2[0]))) &&
+               ether_addr_equal(pCacheEntry->abyAddr2, pMACHeader->addr2) &&
                 (LOBYTE(pCacheEntry->wFrameCtl) == LOBYTE(pMACHeader->frame_control))
                 ) {
                 /* Duplicate match */
@@ -110,8 +109,8 @@ unsigned int WCTLuSearchDFCB(struct vnt_private *pDevice,
 
        for (ii = 0; ii < pDevice->cbDFCB; ii++) {
                if ((pDevice->sRxDFCB[ii].bInUse == true) &&
-                   (!compare_ether_addr(&(pDevice->sRxDFCB[ii].abyAddr2[0]),
-                                         &(pMACHeader->addr2[0])))) {
+                   ether_addr_equal(pDevice->sRxDFCB[ii].abyAddr2,
+                                    pMACHeader->addr2)) {
                        return ii;
                }
        }
index b6cbd138a2b46c615b0870c2c8dca58d094372b5..e26c41519b156dbc04bef2d3ae6e91b0cf0bc017 100644 (file)
@@ -81,7 +81,7 @@
 #include "control.h"
 #include "rndis.h"
 
-static int          msglevel                =MSG_LEVEL_INFO;
+static int msglevel = MSG_LEVEL_INFO;
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 
 static int ChannelExceedZoneType(struct vnt_private *, u8 byCurrChannel);
@@ -213,24 +213,6 @@ void vMgrObjectInit(struct vnt_private *pDevice)
     pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
     BSSvClearBSSList((void *) pDevice, false);
 
-    init_timer(&pMgmt->sTimerSecondCallback);
-    pMgmt->sTimerSecondCallback.data = (unsigned long)pDevice;
-    pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack;
-    pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
-
-    init_timer(&pDevice->sTimerCommand);
-    pDevice->sTimerCommand.data = (unsigned long)pDevice;
-    pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
-    pDevice->sTimerCommand.expires = RUN_AT(HZ);
-
-    init_timer(&pDevice->sTimerTxData);
-    pDevice->sTimerTxData.data = (unsigned long)pDevice;
-    pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
-    pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
-    pDevice->fTxDataInSleep = false;
-    pDevice->IsTxDataTrigger = false;
-    pDevice->nTxDataTimeCout = 0;
-
     pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
     pDevice->uCmdDequeueIdx = 0;
     pDevice->uCmdEnqueueIdx = 0;
@@ -844,8 +826,8 @@ static void s_vMgrRxAssocResponse(struct vnt_private *pDevice,
               pDevice->bwextstep3 = false;
               pDevice->bWPASuppWextEnabled = false;
 
-if(pMgmt->eCurrState == WMAC_STATE_ASSOC)
-      timer_expire(pDevice->sTimerCommand, 0);
+       if (pMgmt->eCurrState == WMAC_STATE_ASSOC)
+               schedule_delayed_work(&pDevice->run_command_work, 0);
 
     return;
 }
@@ -1127,7 +1109,7 @@ static void s_vMgrRxAuthenSequence_2(struct vnt_private *pDevice,
             if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
                 pMgmt->eCurrState = WMAC_STATE_AUTH;
-              timer_expire(pDevice->sTimerCommand, 0);
+               schedule_delayed_work(&pDevice->run_command_work, 0);
             }
             else {
                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n");
@@ -1302,7 +1284,7 @@ static void s_vMgrRxAuthenSequence_4(struct vnt_private *pDevice,
     if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
         pMgmt->eCurrState = WMAC_STATE_AUTH;
-        timer_expire(pDevice->sTimerCommand, 0);
+       schedule_delayed_work(&pDevice->run_command_work, 0);
     }
     else{
         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n");
@@ -1422,8 +1404,8 @@ static void s_vMgrRxDeauthentication(struct vnt_private *pDevice,
           pDevice->fWPA_Authened = false;
             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
             // TODO: update BSS list for specific BSSID if pre-authentication case
-           if (!compare_ether_addr(sFrame.pHdr->sA3.abyAddr3,
-                                   pMgmt->abyCurrBSSID)) {
+           if (ether_addr_equal(sFrame.pHdr->sA3.abyAddr3,
+                                pMgmt->abyCurrBSSID)) {
                 if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
                     pMgmt->sNodeDBTable[0].bActive = false;
                     pMgmt->eCurrMode = WMAC_MODE_STANDBY;
@@ -3095,7 +3077,7 @@ struct vnt_tx_mgmt *s_MgrMakeProbeResponse(struct vnt_private *pDevice,
  *
  *
  * Return Value:
- *    A ptr to frame or NULL on allocation failue
+ *    A ptr to frame or NULL on allocation failure
  *
 -*/
 
index 5424c7f820ade84f57ac0a1af70fcc195b246cea..26ba47da467b0cc81164e534ac4babf4857dd686 100644 (file)
@@ -310,9 +310,6 @@ struct vnt_manager {
        u8 byMgmtPacketPool[sizeof(struct vnt_tx_mgmt)
                + WLAN_A3FR_MAXLEN];
 
-       /* One second callback timer */
-       struct timer_list sTimerSecondCallback;
-
        /* Temporarily Rx Mgmt Packet Descriptor */
        struct vnt_rx_mgmt sRxPacket;
 
index 9f1b413ce86f7534cf7ccc30bb2de26cc0c7ded0..003bd7c614e5f726b9e94109ebef08391dec260c 100644 (file)
@@ -227,7 +227,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx)
                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
                } else {
                        // Key Table Full
-                       if (!compare_ether_addr(&param->addr[0], pDevice->abyBSSID)) {
+                       if (ether_addr_equal(param->addr, pDevice->abyBSSID)) {
                                //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
                                return -EINVAL;
                        } else {
index 560c0ab617d1e2b981555a9aa811857e32e65e33..b031ecd4f3c0302cea95a7cbed6455d123f23173 100644 (file)
@@ -21,6 +21,7 @@
 #include "wbhal.h"
 #include "wb35reg_f.h"
 #include "core.h"
+#include "mto.h"
 
 /* Declare SQ3 to rate and fragmentation threshold table */
 /* Declare fragmentation threshold table */
@@ -45,12 +46,6 @@ static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];
 
 static u8 boSparseTxTraffic;
 
-void MTO_Init(struct wbsoft_priv *adapter);
-void TxRateReductionCtrl(struct wbsoft_priv *adapter);
-void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
-void MTO_TxFailed(struct wbsoft_priv *adapter);
-void hal_get_dto_para(struct wbsoft_priv *adapter, char *buffer);
-
 /*
  * ===========================================================================
  * MTO_Init --
index a0f659cf99ffc84d47d4fb86dc9ab78d105ea7fd..8d41eeda45bf39e612bbfdb21c086434b499ad8a 100644 (file)
@@ -127,12 +127,8 @@ extern u16 MTO_Frag_Th_Tbl[];
 #define MTO_DATA_RATE()                        MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()]
 #define MTO_FRAG_TH()                  MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()]
 
-extern void MTO_Init(struct wbsoft_priv *);
-extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
-extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8);
-extern u8 MTO_GetTxRate(struct wbsoft_priv *adapter, u32 fpdu_len);
-extern u8 MTO_GetTxFallbackRate(struct wbsoft_priv *adapter);
-extern void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
+void MTO_Init(struct wbsoft_priv *);
+void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
 
 #endif /* __MTO_H__ */
 
index cfbfbbb53866cbfd08f31592fc1c78d3c2db6a6a..d970660f6523efa7195491ccfc077dcc2bacf87b 100644 (file)
 #define DEG2RAD(X)      (0.017453 * (X))
 
 static const s32 Angles[] = {
-       FIXED(DEG2RAD(45.0)),     FIXED(DEG2RAD(26.565)),   FIXED(DEG2RAD(14.0362)),
-       FIXED(DEG2RAD(7.12502)),  FIXED(DEG2RAD(3.57633)),  FIXED(DEG2RAD(1.78991)),
-       FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)),
-       FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
+       FIXED(DEG2RAD(45.0)),     FIXED(DEG2RAD(26.565)),
+       FIXED(DEG2RAD(14.0362)),  FIXED(DEG2RAD(7.12502)),
+       FIXED(DEG2RAD(3.57633)),  FIXED(DEG2RAD(1.78991)),
+       FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)),
+       FIXED(DEG2RAD(0.223811)), FIXED(DEG2RAD(0.111906)),
+       FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
 };
 
 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
@@ -296,7 +298,8 @@ void _sin_cos(s32 angle, s32 *sin, s32 *cos)
        }
 }
 
-static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 *pValue)
+static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number,
+                                    u32 *pValue)
 {
        if (number < 0x1000)
                number += 0x1000;
@@ -304,7 +307,8 @@ static unsigned char hal_get_dxx_reg(struct hw_data *pHwData, u16 number, u32 *p
 }
 #define hw_get_dxx_reg(_A, _B, _C) hal_get_dxx_reg(_A, _B, (u32 *)_C)
 
-static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number, u32 value)
+static unsigned char hal_set_dxx_reg(struct hw_data *pHwData, u16 number,
+                                    u32 value)
 {
        unsigned char ret;
 
@@ -407,7 +411,8 @@ void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequen
        PHY_DEBUG(("[CAL]    ** adc_dc_cal_i = %d (0x%04X)\n",
                           _s9_to_s32(val&0x000001FF), val&0x000001FF));
        PHY_DEBUG(("[CAL]    ** adc_dc_cal_q = %d (0x%04X)\n",
-                          _s9_to_s32((val&0x0003FE00)>>9), (val&0x0003FE00)>>9));
+                          _s9_to_s32((val&0x0003FE00)>>9),
+                          (val&0x0003FE00)>>9));
 #endif
 
        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
@@ -535,7 +540,8 @@ void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
                }
 
                PHY_DEBUG(("[CAL]    ** fix_cancel_dc_i = %d (0x%04X)\n",
-                                  fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i)));
+                                  fix_cancel_dc_i,
+                                  _s32_to_s5(fix_cancel_dc_i)));
 
                if ((abs(mag_1-mag_0)*6) > mag_0)
                        break;
@@ -711,7 +717,8 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
        loop = LOOP_TIMES;
 
        while (loop > 0) {
-               PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
+               PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n",
+                                  (LOOP_TIMES-loop+1)));
 
                iqcal_tone_i_avg = 0;
                iqcal_tone_q_avg = 0;
@@ -719,8 +726,8 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        return 0;
                for (capture_time = 0; capture_time < 10; capture_time++) {
                        /*
-                        * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
-                        *    enable "IQ calibration Mode II"
+                        * a. Set iqcal_mode[1:0] to 0x2 and set "calib_start"
+                        *    to 0x1 to enable "IQ calibration Mode II"
                         */
                        reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
                        reg_mode_ctrl &= ~MASK_IQCAL_MODE;
@@ -749,8 +756,8 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        PHY_DEBUG(("[CAL]    MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
 
                        /*
-                        * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
-                        *    enable "IQ calibration Mode II"
+                        * d. Set iqcal_mode[1:0] to 0x3 and set "calib_start"
+                        *    to 0x1 to enable "IQ calibration Mode II"
                         */
                        /* hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val); */
                        hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
@@ -766,7 +773,7 @@ u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
                        iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
                        iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
                        PHY_DEBUG(("[CAL]    ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
-                       iqcal_tone_i, iqcal_tone_q));
+                                          iqcal_tone_i, iqcal_tone_q));
                        if (capture_time == 0)
                                continue;
                        else {
@@ -1146,7 +1153,8 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
        /* for (loop = 0; loop < LOOP_TIMES; loop++) */
        loop = LOOP_TIMES;
        while (loop > 0) {
-               PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
+               PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n",
+                                  (LOOP_TIMES-loop+1)));
                iqcal_tone_i_avg = 0;
                iqcal_tone_q_avg = 0;
                iqcal_image_i_avg = 0;
@@ -1199,13 +1207,13 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
 
                /* d. */
                rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i +
-                                               iqcal_tone_q * iqcal_tone_q) / 1024;
+                                       iqcal_tone_q * iqcal_tone_q) / 1024;
                rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) +
-                                               iqcal_tone_q * iqcal_tone_i) / 1024;
+                                       iqcal_tone_q * iqcal_tone_i) / 1024;
                rot_image_i_b = (iqcal_image_i * iqcal_tone_i -
-                                                iqcal_image_q * iqcal_tone_q) / 1024;
+                                       iqcal_image_q * iqcal_tone_q) / 1024;
                rot_image_q_b = (iqcal_image_i * iqcal_tone_q +
-                                                iqcal_image_q * iqcal_tone_i) / 1024;
+                                       iqcal_image_q * iqcal_tone_i) / 1024;
 
                PHY_DEBUG(("[CAL]    ** rot_tone_i_b  = %d\n", rot_tone_i_b));
                PHY_DEBUG(("[CAL]    ** rot_tone_q_b  = %d\n", rot_tone_q_b));
@@ -1225,8 +1233,10 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
                b_2 = (rot_image_q_b * 32768) / rot_tone_i_b -
                        phw_data->iq_rsdl_phase_tx_d2;
 
-               PHY_DEBUG(("[CAL]    ** iq_rsdl_gain_tx_d2 = %d\n", phw_data->iq_rsdl_gain_tx_d2));
-               PHY_DEBUG(("[CAL]    ** iq_rsdl_phase_tx_d2= %d\n", phw_data->iq_rsdl_phase_tx_d2));
+               PHY_DEBUG(("[CAL]    ** iq_rsdl_gain_tx_d2 = %d\n",
+                          phw_data->iq_rsdl_gain_tx_d2));
+               PHY_DEBUG(("[CAL]    ** iq_rsdl_phase_tx_d2= %d\n",
+                          phw_data->iq_rsdl_phase_tx_d2));
                PHY_DEBUG(("[CAL]    ***** EPSILON/2 = %d\n", a_2));
                PHY_DEBUG(("[CAL]    ***** THETA/2   = %d\n", b_2));
 
@@ -1272,7 +1282,8 @@ u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 fre
 
                /* e. */
                pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q);
-               pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor;
+               pwr_image = (iqcal_image_i*iqcal_image_i +
+                            iqcal_image_q*iqcal_image_q)*factor;
 
                PHY_DEBUG(("[CAL]    ** pwr_tone  = %d\n", pwr_tone));
                PHY_DEBUG(("[CAL]    ** pwr_image  = %d\n", pwr_image));
@@ -1569,7 +1580,8 @@ unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
 
                sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0;
                iq_mag_0_tx = (s32) _sqrt(sqsum);
-               PHY_DEBUG(("[CAL]    ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
+               PHY_DEBUG(("[CAL]    ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n",
+                          iq_mag_0_tx));
 
                if (iq_mag_0_tx >= 700 && iq_mag_0_tx <= 1750)
                        break;
index 75b775252af1ee4364e32939856216a4dcfd6175..80b4b343a94eec115a3fe200deba3df88d2e0b5c 100644 (file)
@@ -920,7 +920,7 @@ void Uxx_power_on_procedure(struct hw_data *pHwData)
        Wb35Reg_WriteSync(pHwData, 0x03f8, 0x7ff);
 }
 
-static void Set_ChanIndep_RfData_al7230_24(struct hw_data *pHwData, u32 *pltmp, 
+static void Set_ChanIndep_RfData_al7230_24(struct hw_data *pHwData, u32 *pltmp,
                                        char number)
 {
        u8      i;
@@ -930,7 +930,7 @@ static void Set_ChanIndep_RfData_al7230_24(struct hw_data *pHwData, u32 *pltmp,
        }
 }
 
-static void Set_ChanIndep_RfData_al7230_50(struct hw_data *pHwData, u32 *pltmp, 
+static void Set_ChanIndep_RfData_al7230_50(struct hw_data *pHwData, u32 *pltmp,
                                        char number)
 {
        u8      i;
@@ -1088,7 +1088,7 @@ void RFSynthesizer_initial(struct hw_data *pHwData)
                msleep(5);
 
                ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse((0x0F << 20) | 0xF01A0, 20);
-               Wb35Reg_WriteSync(pHwData, 0x0864, ltmp) ;
+               Wb35Reg_WriteSync(pHwData, 0x0864, ltmp);
 
                Wb35Reg_WriteSync(pHwData, 0x105c, pHwData->reg.BB5C);
                pHwData->reg.BB50 &= ~0x13; /* (MASK_IQCAL_MODE|MASK_CALIB_START); */
@@ -1620,13 +1620,13 @@ void BBProcessor_initial(struct hw_data *pHwData)
                reg->SQ3_filter[i] = 0x2f; /* half of Bit 0 ~ 6 */
 }
 
-static inline void set_tx_power_per_channel_max2829(struct hw_data *pHwData,  
+static inline void set_tx_power_per_channel_max2829(struct hw_data *pHwData,
                                                struct chan_info Channel)
 {
        RFSynthesizer_SetPowerIndex(pHwData, 100);
 }
 
-static void set_tx_power_per_channel_al2230(struct hw_data *pHwData,  
+static void set_tx_power_per_channel_al2230(struct hw_data *pHwData,
                                        struct chan_info Channel)
 {
        u8      index = 100;
@@ -1636,7 +1636,7 @@ static void set_tx_power_per_channel_al2230(struct hw_data *pHwData,
        RFSynthesizer_SetPowerIndex(pHwData, index);
 }
 
-static void set_tx_power_per_channel_al7230(struct hw_data *pHwData,  
+static void set_tx_power_per_channel_al7230(struct hw_data *pHwData,
                                        struct chan_info Channel)
 {
        u8      i, index = 100;
@@ -1660,7 +1660,7 @@ static void set_tx_power_per_channel_al7230(struct hw_data *pHwData,
        RFSynthesizer_SetPowerIndex(pHwData, index);
 }
 
-static void set_tx_power_per_channel_wb242(struct hw_data *pHwData,  
+static void set_tx_power_per_channel_wb242(struct hw_data *pHwData,
                                        struct chan_info Channel)
 {
        u8      index = 100;
@@ -2096,7 +2096,7 @@ void Mxx_initial(struct hw_data *pHwData)
        pltmp[5] = reg->M38_MacControl;
 
        /* M3C */
-       tmp = (DEFAULT_PIFST << 26) | (DEFAULT_EIFST << 16) | (DEFAULT_DIFST << 8) | (DEFAULT_SIFST << 4) | DEFAULT_OSIFST ;
+       tmp = (DEFAULT_PIFST << 26) | (DEFAULT_EIFST << 16) | (DEFAULT_DIFST << 8) | (DEFAULT_SIFST << 4) | DEFAULT_OSIFST;
        reg->M3C_MacControl = tmp;
        pltmp[6] = tmp;
 
index 30a77ccfe48069d684ce469b5812377f65628655..708c5b05f86c6e929d98fe8e4f9512970a37d525 100644 (file)
@@ -180,7 +180,7 @@ void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount)
 {
        struct hw_data *pHwData = &adapter->sHwData;
        struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
-       unsigned char Trigger = false;
+       bool Trigger = false;
 
        if (pWb35Tx->TxTimer > TimeCount)
                Trigger = true;
index 2abeaa11d8ca3d60d4c01da5fa24afab2f7ac763..71b44653690c4d179b99903c81d9e28280634aa0 100644 (file)
@@ -372,22 +372,22 @@ typedef IFB_STRCT*        IFBP;
 /**********************   W C I    F U N C T I O N S    P R O T O T Y P E S   ******************************/
 /***********************************************************************************************************/
 
-EXTERN_C int            hcf_action                     (IFBP ifbp, hcf_16 cmd );
-EXTERN_C int            hcf_connect            (IFBP ifbp, hcf_io io_base );
-EXTERN_C int            hcf_get_info           (IFBP ifbp, LTVP ltvp );
-EXTERN_C int            hcf_service_nic        (IFBP ifbp, wci_bufp bufp, unsigned int len );
-EXTERN_C int            hcf_cntl                       (IFBP ifbp, hcf_16 cmd );
-EXTERN_C int            hcf_put_info           (IFBP ifbp, LTVP ltvp );
-EXTERN_C int            hcf_rcv_msg            (IFBP ifbp, DESC_STRCT *descp, unsigned int offset );
-EXTERN_C int            hcf_send_msg       (IFBP ifbp, DESC_STRCT *dp, hcf_16 tx_cntl );
+EXTERN_C int hcf_action(IFBP ifbp, hcf_16 cmd);
+EXTERN_C int hcf_connect(IFBP ifbp, hcf_io io_base);
+EXTERN_C int hcf_get_info(IFBP ifbp, LTVP ltvp);
+EXTERN_C int hcf_service_nic(IFBP ifbp, wci_bufp bufp, unsigned int len);
+EXTERN_C int hcf_cntl(IFBP ifbp, hcf_16 cmd);
+EXTERN_C int hcf_put_info(IFBP ifbp, LTVP ltvp);
+EXTERN_C int hcf_rcv_msg(IFBP ifbp, DESC_STRCT *descp, unsigned int offset);
+EXTERN_C int hcf_send_msg(IFBP ifbp, DESC_STRCT *dp, hcf_16 tx_cntl);
 #if HCF_DMA
-EXTERN_C void           hcf_dma_tx_put         (IFBP ifbp, DESC_STRCT *d, hcf_16 tx_cntl );
+EXTERN_C void hcf_dma_tx_put(IFBP ifbp, DESC_STRCT *d, hcf_16 tx_cntl);
 EXTERN_C DESC_STRCT* hcf_dma_tx_get            (IFBP ifbp );
 EXTERN_C DESC_STRCT* hcf_dma_rx_get            (IFBP ifbp );
-EXTERN_C void           hcf_dma_rx_put         (IFBP ifbp, DESC_STRCT *d );
+EXTERN_C void hcf_dma_rx_put(IFBP ifbp, DESC_STRCT *d);
 #endif // HCF_DMA
 #if (HCF_ASSERT) & HCF_ASSERT_LNK_MSF_RTN
-EXTERN_C void           msf_assert                     (unsigned int line_number, hcf_16 trace, hcf_32 qual );
+EXTERN_C void msf_assert(unsigned int line_number, hcf_16 trace, hcf_32 qual);
 #endif // HCF_ASSERT_LNK_MSF_RTN
 
 #endif  // HCF_H
index 19bed819df1e7e6f1ee4b3f68657953d4a31f870..25ac76f7d366ea70468fb7819e84bdfb05cae5bf 100644 (file)
@@ -4472,8 +4472,8 @@ memimage fw_image = {
        "FUPU7D37dhfwci\001C",                  /* signature, <format number>, C/Bin type */
        (CFG_PROG_STRCT *) fw_image_code,
        0x000F368E,
-       00000000,                                       /* (dummy) pdaplug */
-       00000000,                                       /* (dummy) priplug */
+       NULL,                                   /* (dummy) pdaplug */
+       NULL,                                   /* (dummy) priplug */
        (CFG_RANGE20_STRCT *) fw_image_infocompat,
        (CFG_IDENTITY_STRCT *) fw_image_infoidentity,
 };
index f1bce18ea828fe4f957705ec342508b16670f99a..a4fd5c4717a880d7c68eefaf939062eabbb4c02a 100644 (file)
@@ -98,10 +98,10 @@ static int prism2_domibset_pstr32(wlandevice_t *wlandev,
 
 
 /* The interface functions, called by the cfg80211 layer */
-int prism2_change_virtual_intf(struct wiphy *wiphy,
-                              struct net_device *dev,
-                              enum nl80211_iftype type, u32 *flags,
-                              struct vif_params *params)
+static int prism2_change_virtual_intf(struct wiphy *wiphy,
+                                     struct net_device *dev,
+                                     enum nl80211_iftype type, u32 *flags,
+                                     struct vif_params *params)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        u32 data;
@@ -122,7 +122,7 @@ int prism2_change_virtual_intf(struct wiphy *wiphy,
                data = 1;
                break;
        default:
-               printk(KERN_WARNING "Operation mode: %d not support\n", type);
+               netdev_warn(dev, "Operation mode: %d not support\n", type);
                return -EOPNOTSUPP;
        }
 
@@ -140,9 +140,9 @@ exit:
        return err;
 }
 
-int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
-                  u8 key_index, bool pairwise, const u8 *mac_addr,
-                  struct key_params *params)
+static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
+                         u8 key_index, bool pairwise, const u8 *mac_addr,
+                         struct key_params *params)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        u32 did;
@@ -199,9 +199,10 @@ exit:
        return err;
 }
 
-int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
-                  u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie,
-                  void (*callback)(void *cookie, struct key_params*))
+static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
+                         u8 key_index, bool pairwise,
+                         const u8 *mac_addr, void *cookie,
+                         void (*callback)(void *cookie, struct key_params*))
 {
        wlandevice_t *wlandev = dev->ml_priv;
        struct key_params params;
@@ -228,8 +229,8 @@ int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
        return 0;
 }
 
-int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
-                  u8 key_index, bool pairwise, const u8 *mac_addr)
+static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
+                         u8 key_index, bool pairwise, const u8 *mac_addr)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        u32 did;
@@ -274,8 +275,8 @@ exit:
        return err;
 }
 
-int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
-                          u8 key_index, bool unicast, bool multicast)
+static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
+                                 u8 key_index, bool unicast, bool multicast)
 {
        wlandevice_t *wlandev = dev->ml_priv;
 
@@ -293,8 +294,8 @@ int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
 }
 
 
-int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
-                      u8 *mac, struct station_info *sinfo)
+static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
+                             u8 *mac, struct station_info *sinfo)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        struct p80211msg_lnxreq_commsquality quality;
@@ -327,7 +328,7 @@ int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
        return result;
 }
 
-int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
+static int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 {
        struct net_device *dev;
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
@@ -352,7 +353,7 @@ int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
                return -EBUSY;
 
        if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
-               printk(KERN_ERR "Can't scan in AP mode\n");
+               netdev_err(dev, "Can't scan in AP mode\n");
                return -EOPNOTSUPP;
        }
 
@@ -436,7 +437,7 @@ exit:
        return err;
 }
 
-int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+static int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
 {
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
        wlandevice_t *wlandev = priv->wlandev;
@@ -478,8 +479,8 @@ exit:
        return err;
 }
 
-int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
-                  struct cfg80211_connect_params *sme)
+static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
+                         struct cfg80211_connect_params *sme)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        struct ieee80211_channel *channel = sme->channel;
@@ -510,7 +511,7 @@ int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
                ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
                        msg_join.authtype.data = P80211ENUM_authalg_sharedkey;
        else
-               printk(KERN_WARNING
+               netdev_warn(dev,
                        "Unhandled authorisation type for connect (%d)\n",
                        sme->auth_type);
 
@@ -602,8 +603,8 @@ exit:
        return err;
 }
 
-int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
-                     u16 reason_code)
+static int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
+                            u16 reason_code)
 {
        wlandevice_t *wlandev = dev->ml_priv;
        struct p80211msg_lnxreq_autojoin msg_join;
@@ -626,20 +627,20 @@ int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
 }
 
 
-int prism2_join_ibss(struct wiphy *wiphy, struct net_device *dev,
-                    struct cfg80211_ibss_params *params)
+static int prism2_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+                           struct cfg80211_ibss_params *params)
 {
        return -EOPNOTSUPP;
 }
 
-int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+static int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 {
        return -EOPNOTSUPP;
 }
 
 
-int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
-                       enum nl80211_tx_power_setting type, int mbm)
+static int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
+                              enum nl80211_tx_power_setting type, int mbm)
 {
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
        wlandevice_t *wlandev = priv->wlandev;
@@ -665,8 +666,8 @@ exit:
        return err;
 }
 
-int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
-                       int *dbm)
+static int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
+                              int *dbm)
 {
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
        wlandevice_t *wlandev = priv->wlandev;
index c1a8cb62515445741b914cb8734dcbe0d7b4553a..5b8b094c87261807d49d2b68b3e518033b17a13f 100644 (file)
@@ -355,7 +355,7 @@ static int submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
 
                /* Check whether we need to reset the RX pipe */
                if (result == -EPIPE) {
-                       printk(KERN_WARNING
+                       netdev_warn(hw->wlandev->netdev,
                               "%s rx pipe stalled: requesting reset\n",
                               hw->wlandev->netdev->name);
                        if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
@@ -405,7 +405,7 @@ static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
 
                        /* Test whether we need to reset the TX pipe */
                        if (result == -EPIPE) {
-                               printk(KERN_WARNING
+                               netdev_warn(hw->wlandev->netdev,
                                       "%s tx pipe stalled: requesting reset\n",
                                       netdev->name);
                                set_bit(WORK_TX_HALT, &hw->usb_flags);
@@ -454,11 +454,11 @@ static void hfa384x_usb_defer(struct work_struct *data)
 
                ret = usb_clear_halt(hw->usb, hw->endp_in);
                if (ret != 0) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Failed to clear rx pipe for %s: err=%d\n",
                               netdev->name, ret);
                } else {
-                       printk(KERN_INFO "%s rx pipe reset complete.\n",
+                       netdev_info(hw->wlandev->netdev, "%s rx pipe reset complete.\n",
                               netdev->name);
                        clear_bit(WORK_RX_HALT, &hw->usb_flags);
                        set_bit(WORK_RX_RESUME, &hw->usb_flags);
@@ -471,7 +471,7 @@ static void hfa384x_usb_defer(struct work_struct *data)
 
                ret = submit_rx_urb(hw, GFP_KERNEL);
                if (ret != 0) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Failed to resume %s rx pipe.\n", netdev->name);
                } else {
                        clear_bit(WORK_RX_RESUME, &hw->usb_flags);
@@ -485,11 +485,11 @@ static void hfa384x_usb_defer(struct work_struct *data)
                usb_kill_urb(&hw->tx_urb);
                ret = usb_clear_halt(hw->usb, hw->endp_out);
                if (ret != 0) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Failed to clear tx pipe for %s: err=%d\n",
                               netdev->name, ret);
                } else {
-                       printk(KERN_INFO "%s tx pipe reset complete.\n",
+                       netdev_info(hw->wlandev->netdev, "%s tx pipe reset complete.\n",
                               netdev->name);
                        clear_bit(WORK_TX_HALT, &hw->usb_flags);
                        set_bit(WORK_TX_RESUME, &hw->usb_flags);
@@ -1211,7 +1211,7 @@ int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
 
        result = usb_reset_device(hw->usb);
        if (result < 0) {
-               printk(KERN_ERR "usb_reset_device() failed, result=%d.\n",
+               netdev_err(hw->wlandev->netdev, "usb_reset_device() failed, result=%d.\n",
                       result);
        }
 
@@ -1311,7 +1311,7 @@ cleanup:
                if (ctlx->state == CTLX_COMPLETE) {
                        result = completor->complete(completor);
                } else {
-                       printk(KERN_WARNING "CTLX[%d] error: state(%s)\n",
+                       netdev_warn(hw->wlandev->netdev, "CTLX[%d] error: state(%s)\n",
                               le16_to_cpu(ctlx->outbuf.type),
                               ctlxstr(ctlx->state));
                        result = -EIO;
@@ -2018,7 +2018,7 @@ int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
        if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
                return -EINVAL;
 
-       printk(KERN_INFO "Download %d bytes to flash @0x%06x\n", len, daddr);
+       netdev_info(hw->wlandev->netdev, "Download %d bytes to flash @0x%06x\n", len, daddr);
 
        /* Convert to flat address for arithmetic */
        /* NOTE: dlbuffer RID stores the address in AUX format */
@@ -2028,7 +2028,7 @@ int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
                 hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);
 
 #if 0
-       printk(KERN_WARNING "dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr,
+       netdev_warn(hw->wlandev->netdev, "dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr,
               hw->bufinfo.len, hw->dltimeout);
 #endif
        /* Calculations to determine how many fills of the dlbuffer to do
@@ -2055,14 +2055,14 @@ int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
                burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr);
                burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr);
 
-               printk(KERN_INFO "Writing %d bytes to flash @0x%06x\n",
+               netdev_info(hw->wlandev->netdev, "Writing %d bytes to flash @0x%06x\n",
                       burnlen, burndaddr);
 
                /* Set the download mode */
                result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
                                              burnlo, burnhi, burnlen);
                if (result) {
-                       printk(KERN_ERR "download(NV,lo=%x,hi=%x,len=%x) "
+                       netdev_err(hw->wlandev->netdev, "download(NV,lo=%x,hi=%x,len=%x) "
                               "cmd failed, result=%d. Aborting d/l\n",
                               burnlo, burnhi, burnlen, result);
                        goto exit_proc;
@@ -2094,7 +2094,7 @@ int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
                                              HFA384x_PROGMODE_NVWRITE,
                                              0, 0, 0);
                if (result) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "download(NVWRITE,lo=%x,hi=%x,len=%x) "
                               "cmd failed, result=%d. Aborting d/l\n",
                               burnlo, burnhi, burnlen, result);
@@ -2279,7 +2279,7 @@ int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
        /* Check that a port isn't active */
        for (i = 0; i < HFA384x_PORTID_MAX; i++) {
                if (hw->port_enabled[i]) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Can't download with a macport enabled.\n");
                        return -EINVAL;
                }
@@ -2287,7 +2287,7 @@ int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
 
        /* Check that we're not already in a download state */
        if (hw->dlstate != HFA384x_DLSTATE_DISABLED) {
-               printk(KERN_ERR "Download state not disabled.\n");
+               netdev_err(hw->wlandev->netdev, "Download state not disabled.\n");
                return -EINVAL;
        }
 
@@ -2352,7 +2352,7 @@ int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
        if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
                return -EINVAL;
 
-       printk(KERN_INFO "Writing %d bytes to ram @0x%06x\n", len, daddr);
+       netdev_info(hw->wlandev->netdev, "Writing %d bytes to ram @0x%06x\n", len, daddr);
 
        /* How many dowmem calls?  */
        nwrites = len / HFA384x_USB_RWMEM_MAXLEN;
@@ -2449,7 +2449,7 @@ int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
                                                len);
 
                if (result) {
-                       printk(KERN_WARNING
+                       netdev_warn(hw->wlandev->netdev,
                               "Read from index %zd failed, continuing\n", i);
                        continue;
                }
@@ -2462,13 +2462,13 @@ int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
                        pdrcode = le16_to_cpu(pda[currpdr + 1]);
                        /* Test the record length */
                        if (pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
-                               printk(KERN_ERR "pdrlen invalid=%d\n", pdrlen);
+                               netdev_err(hw->wlandev->netdev, "pdrlen invalid=%d\n", pdrlen);
                                pdaok = 0;
                                break;
                        }
                        /* Test the code */
                        if (!hfa384x_isgood_pdrcode(pdrcode)) {
-                               printk(KERN_ERR "pdrcode invalid=%d\n",
+                               netdev_err(hw->wlandev->netdev, "pdrcode invalid=%d\n",
                                       pdrcode);
                                pdaok = 0;
                                break;
@@ -2484,7 +2484,7 @@ int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
                        }
                }
                if (pdaok) {
-                       printk(KERN_INFO
+                       netdev_info(hw->wlandev->netdev,
                               "PDA Read from 0x%08x in %s space.\n",
                               pdaloc[i].cardaddr,
                               pdaloc[i].auxctl == 0 ? "EXTDS" :
@@ -2564,20 +2564,20 @@ int hfa384x_drvr_start(hfa384x_t *hw)
        result =
            usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status);
        if (result < 0) {
-               printk(KERN_ERR "Cannot get bulk in endpoint status.\n");
+               netdev_err(hw->wlandev->netdev, "Cannot get bulk in endpoint status.\n");
                goto done;
        }
        if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in))
-               printk(KERN_ERR "Failed to reset bulk in endpoint.\n");
+               netdev_err(hw->wlandev->netdev, "Failed to reset bulk in endpoint.\n");
 
        result =
            usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status);
        if (result < 0) {
-               printk(KERN_ERR "Cannot get bulk out endpoint status.\n");
+               netdev_err(hw->wlandev->netdev, "Cannot get bulk out endpoint status.\n");
                goto done;
        }
        if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out))
-               printk(KERN_ERR "Failed to reset bulk out endpoint.\n");
+               netdev_err(hw->wlandev->netdev, "Failed to reset bulk out endpoint.\n");
 
        /* Synchronous unlink, in case we're trying to restart the driver */
        usb_kill_urb(&hw->rx_urb);
@@ -2585,7 +2585,7 @@ int hfa384x_drvr_start(hfa384x_t *hw)
        /* Post the IN urb */
        result = submit_rx_urb(hw, GFP_KERNEL);
        if (result != 0) {
-               printk(KERN_ERR
+               netdev_err(hw->wlandev->netdev,
                       "Fatal, failed to submit RX URB, result=%d\n", result);
                goto done;
        }
@@ -2605,7 +2605,7 @@ int hfa384x_drvr_start(hfa384x_t *hw)
        result = result2 = hfa384x_cmd_initialize(hw);
        if (result1 != 0) {
                if (result2 != 0) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                                "cmd_initialize() failed on two attempts, results %d and %d\n",
                                result1, result2);
                        usb_kill_urb(&hw->rx_urb);
@@ -2616,9 +2616,9 @@ int hfa384x_drvr_start(hfa384x_t *hw)
                        pr_debug("but second attempt succeeded. All should be ok\n");
                }
        } else if (result2 != 0) {
-               printk(KERN_WARNING "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
+               netdev_warn(hw->wlandev->netdev, "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
                        result2);
-               printk(KERN_WARNING
+               netdev_warn(hw->wlandev->netdev,
                       "Most likely the card will be functional\n");
                goto done;
        }
@@ -2709,7 +2709,7 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
        char *ptr;
 
        if (hw->tx_urb.status == -EINPROGRESS) {
-               printk(KERN_WARNING "TX URB already in use\n");
+               netdev_warn(hw->wlandev->netdev, "TX URB already in use\n");
                result = 3;
                goto exit;
        }
@@ -2784,7 +2784,7 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
        result = 1;
        ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC);
        if (ret != 0) {
-               printk(KERN_ERR "submit_tx_urb() failed, error=%d\n", ret);
+               netdev_err(hw->wlandev->netdev, "submit_tx_urb() failed, error=%d\n", ret);
                result = 3;
        }
 
@@ -3009,7 +3009,7 @@ static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
                break;
 
        default:
-               printk(KERN_ERR "CTLX[%d] not in a terminating state(%s)\n",
+               netdev_err(hw->wlandev->netdev, "CTLX[%d] not in a terminating state(%s)\n",
                       le16_to_cpu(ctlx->outbuf.type), ctlxstr(ctlx->state));
                break;
        }                       /* switch */
@@ -3091,7 +3091,7 @@ static void hfa384x_usbctlxq_run(hfa384x_t *hw)
                         * this CTLX back in the "pending" queue
                         * and schedule a reset ...
                         */
-                       printk(KERN_WARNING
+                       netdev_warn(hw->wlandev->netdev,
                               "%s tx pipe stalled: requesting reset\n",
                               hw->wlandev->netdev->name);
                        list_move(&head->list, &hw->ctlxq.pending);
@@ -3101,12 +3101,12 @@ static void hfa384x_usbctlxq_run(hfa384x_t *hw)
                }
 
                if (result == -ESHUTDOWN) {
-                       printk(KERN_WARNING "%s urb shutdown!\n",
+                       netdev_warn(hw->wlandev->netdev, "%s urb shutdown!\n",
                               hw->wlandev->netdev->name);
                        break;
                }
 
-               printk(KERN_ERR "Failed to submit CTLX[%d]: error=%d\n",
+               netdev_err(hw->wlandev->netdev, "Failed to submit CTLX[%d]: error=%d\n",
                       le16_to_cpu(head->outbuf.type), result);
                unlocked_usbctlx_complete(hw, head);
        }                       /* while */
@@ -3173,7 +3173,7 @@ static void hfa384x_usbin_callback(struct urb *urb)
                break;
 
        case -EPIPE:
-               printk(KERN_WARNING "%s rx pipe stalled: requesting reset\n",
+               netdev_warn(hw->wlandev->netdev, "%s rx pipe stalled: requesting reset\n",
                       wlandev->netdev->name);
                if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
                        schedule_work(&hw->usb_work);
@@ -3224,7 +3224,7 @@ static void hfa384x_usbin_callback(struct urb *urb)
                result = submit_rx_urb(hw, GFP_ATOMIC);
 
                if (result != 0) {
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Fatal, failed to resubmit rx_urb. error=%d\n",
                               result);
                }
@@ -3360,7 +3360,7 @@ retry:
                 * Check that our message is what we're expecting ...
                 */
                if (ctlx->outbuf.type != intype) {
-                       printk(KERN_WARNING
+                       netdev_warn(hw->wlandev->netdev,
                               "Expected IN[%d], received IN[%d] - ignored.\n",
                               le16_to_cpu(ctlx->outbuf.type),
                               le16_to_cpu(intype));
@@ -3396,7 +3396,7 @@ retry:
                        /*
                         * Throw this CTLX away ...
                         */
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                               "Matched IN URB, CTLX[%d] in invalid state(%s)."
                               " Discarded.\n",
                               le16_to_cpu(ctlx->outbuf.type),
@@ -3534,7 +3534,7 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
                break;
 
        default:
-               printk(KERN_WARNING "Received frame on unsupported port=%d\n",
+               netdev_warn(hw->wlandev->netdev, "Received frame on unsupported port=%d\n",
                       HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status));
                goto done;
                break;
@@ -3596,7 +3596,7 @@ static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
 
        skb = dev_alloc_skb(skblen);
        if (skb == NULL) {
-               printk(KERN_ERR
+               netdev_err(hw->wlandev->netdev,
                       "alloc_skb failed trying to allocate %d bytes\n",
                       skblen);
                return;
@@ -3714,7 +3714,7 @@ static void hfa384x_usbout_callback(struct urb *urb)
                case -EPIPE:
                        {
                                hfa384x_t *hw = wlandev->priv;
-                               printk(KERN_WARNING
+                               netdev_warn(hw->wlandev->netdev,
                                       "%s tx pipe stalled: requesting reset\n",
                                       wlandev->netdev->name);
                                if (!test_and_set_bit
@@ -3747,7 +3747,7 @@ static void hfa384x_usbout_callback(struct urb *urb)
                        break;
 
                default:
-                       printk(KERN_INFO "unknown urb->status=%d\n",
+                       netdev_info(wlandev->netdev, "unknown urb->status=%d\n",
                               urb->status);
                        ++(wlandev->linux_stats.tx_errors);
                        break;
@@ -3841,7 +3841,7 @@ retry:
 
                default:
                        /* This is NOT a valid CTLX "success" state! */
-                       printk(KERN_ERR
+                       netdev_err(hw->wlandev->netdev,
                                "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
                                le16_to_cpu(ctlx->outbuf.type),
                                ctlxstr(ctlx->state), urb->status);
@@ -3851,7 +3851,7 @@ retry:
                /* If the pipe has stalled then we need to reset it */
                if ((urb->status == -EPIPE) &&
                    !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags)) {
-                       printk(KERN_WARNING
+                       netdev_warn(hw->wlandev->netdev,
                               "%s tx pipe stalled: requesting reset\n",
                               hw->wlandev->netdev->name);
                        schedule_work(&hw->usb_work);
index 2fecca2302f437a2e368b2a1eed767e76f4b2e5d..2e0bd24f997cd834420fa4125c6e3262e43aaa29 100644 (file)
@@ -138,7 +138,7 @@ typedef struct p80211_frmrx_t {
 } p80211_frmrx_t;
 
 /* called by /proc/net/wireless */
-struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t * dev);
+struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t *dev);
 /* wireless extensions' ioctls */
 extern struct iw_handler_def p80211wext_handler_def;
 int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
index 77e50a4aa7e9430c1ff59ea3136f5abf9a50b457..c4fabadf5d74c081c70741ce793bc28392851829 100644 (file)
@@ -134,7 +134,7 @@ int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen)
                return -1;
 
 #ifdef WEP_DEBUG
-       printk(KERN_DEBUG "WEP key %d len %d = %*phC\n", keynum, keylen,
+       pr_debug("WEP key %d len %d = %*phC\n", keynum, keylen,
                          8, key);
 #endif
 
@@ -182,7 +182,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
        keylen += 3;            /* add in IV bytes */
 
 #ifdef WEP_DEBUG
-       printk(KERN_DEBUG "D %d: %*ph (%d %d) %*phC\n", len, 3, key,
+       pr_debug("D %d: %*ph (%d %d) %*phC\n", len, 3, key,
                          keyidx, keylen, 5, key + 3);
 #endif
 
@@ -259,7 +259,7 @@ int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
        keylen += 3;            /* add in IV bytes */
 
 #ifdef WEP_DEBUG
-       printk(KERN_DEBUG "E %d (%d/%d %d) %*ph %*phC\n", len,
+       pr_debug("E %d (%d/%d %d) %*ph %*phC\n", len,
                          iv[3], keynum, keylen, 3, key, 5, key + 3);
 #endif
 
index 3b3e17d3f6f58a057cc6c2b014574044f01688a3..b3ff603e6225dec31b2c24cef8832e06365ffcf4 100644 (file)
@@ -2070,7 +2070,6 @@ static void xgifb_remove(struct pci_dev *pdev)
        release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
        pci_disable_device(pdev);
        framebuffer_release(fb_info);
-       pci_set_drvdata(pdev, NULL);
 }
 
 static struct pci_driver xgifb_driver = {
index 46dea3f1088805749a1a6a9b449117fb827fc91d..eed58f9a0ad5594ec25c361943b661f67efaaab9 100644 (file)
@@ -5274,9 +5274,8 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
 
        outb(0x00, pVBInfo->P3c8);
 
-       for (i = 0; i < 256 * 3; i++) {
+       for (i = 0; i < 256 * 3; i++)
                outb(0x0F, (pVBInfo->P3c8 + 1)); /* DAC_TEST_PARMS */
-       }
 
        mdelay(1);
 
@@ -5291,9 +5290,8 @@ void XGI_SenseCRT1(struct vb_device_info *pVBInfo)
        /* avoid display something, set BLACK DAC if not restore DAC */
        outb(0x00, pVBInfo->P3c8);
 
-       for (i = 0; i < 256 * 3; i++) {
+       for (i = 0; i < 256 * 3; i++)
                outb(0, (pVBInfo->P3c8 + 1));
-       }
 
        xgifb_reg_set(pVBInfo->P3c4, 0x01, SR01);
        xgifb_reg_set(pVBInfo->P3d4, 0x63, CR63);
index 7168eedbd96a1bb471666af8b74a1fa2c08249a0..f17e5b9bd3330c61baa515a18b528c0b26e14393 100644 (file)
@@ -1284,7 +1284,7 @@ static const struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = {
        {0, 1048,   0, 771}, /* 04 (640x480x60Hz) */
        {0, 1048,   0, 771}, /* 05 (800x600x60Hz) */
        {0, 1048, 805, 770}  /* 06 (1024x768x60Hz) */
-} ;
+};
 
 static const struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = {
        {1142,  856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
index 8a4181f846a107df9b68b1bf1e8cdc5b94930332..b15f778b4c6815e43a4320cd94862e79dfe4b529 100644 (file)
@@ -16,14 +16,14 @@ if XILLYBUS
 
 config XILLYBUS_PCIE
        tristate "Xillybus over PCIe"
-       depends on XILLYBUS && PCI
+       depends on PCI
        help
          Set to M if you want Xillybus to use PCI Express for communicating
          with the FPGA.
 
 config XILLYBUS_OF
        tristate "Xillybus over Device Tree"
-       depends on XILLYBUS && OF_ADDRESS && OF_IRQ
+       depends on OF_ADDRESS && OF_IRQ
        help
          Set to M if you want Xillybus to find its resources from the
          Open Firmware Flattened Device Tree. If the target is an embedded
index 7db6f03a00540cd8c2a131ab7039fec6251b72cc..2ebaf166038c6e939435f19e1386e752b12bf356 100644 (file)
@@ -101,7 +101,7 @@ static struct workqueue_struct *xillybus_wq;
  * wr_mutex -> rd_mutex -> register_mutex -> wr_spinlock -> rd_spinlock
  */
 
-static void malformed_message(u32 *buf)
+static void malformed_message(struct xilly_endpoint *endpoint, u32 *buf)
 {
        int opcode;
        int msg_channel, msg_bufno, msg_data, msg_dir;
@@ -112,9 +112,9 @@ static void malformed_message(u32 *buf)
        msg_bufno = (buf[0] >> 12) & 0x3ff;
        msg_data = buf[1] & 0xfffffff;
 
-       pr_warn("xillybus: Malformed message (skipping): "
-               "opcode=%d, channel=%03x, dir=%d, bufno=%03x, data=%07x\n",
-               opcode, msg_channel, msg_dir, msg_bufno, msg_data);
+       dev_warn(endpoint->dev,
+                "Malformed message (skipping): opcode=%d, channel=%03x, dir=%d, bufno=%03x, data=%07x\n",
+                opcode, msg_channel, msg_dir, msg_bufno, msg_data);
 }
 
 /*
@@ -152,16 +152,16 @@ irqreturn_t xillybus_isr(int irq, void *data)
 
        for (i = 0; i < buf_size; i += 2)
                if (((buf[i+1] >> 28) & 0xf) != ep->msg_counter) {
-                       malformed_message(&buf[i]);
-                       pr_warn("xillybus: Sending a NACK on "
-                               "counter %x (instead of %x) on entry %d\n",
+                       malformed_message(ep, &buf[i]);
+                       dev_warn(ep->dev,
+                                "Sending a NACK on counter %x (instead of %x) on entry %d\n",
                                ((buf[i+1] >> 28) & 0xf),
                                ep->msg_counter,
                                i/2);
 
                        if (++ep->failed_messages > 10)
-                               pr_err("xillybus: Lost sync with "
-                                      "interrupt messages. Stopping.\n");
+                               dev_err(ep->dev,
+                                       "Lost sync with interrupt messages. Stopping.\n");
                        else {
                                ep->ephw->hw_sync_sgl_for_device(
                                        ep,
@@ -177,7 +177,7 @@ irqreturn_t xillybus_isr(int irq, void *data)
                        break;
 
        if (i >= buf_size) {
-               pr_err("xillybus: Bad interrupt message. Stopping.\n");
+               dev_err(ep->dev, "Bad interrupt message. Stopping.\n");
                return IRQ_HANDLED;
        }
 
@@ -196,7 +196,7 @@ irqreturn_t xillybus_isr(int irq, void *data)
 
                        if ((msg_channel > ep->num_channels) ||
                            (msg_channel == 0)) {
-                               malformed_message(&buf[i]);
+                               malformed_message(ep, &buf[i]);
                                break;
                        }
 
@@ -204,7 +204,7 @@ irqreturn_t xillybus_isr(int irq, void *data)
 
                        if (msg_dir) { /* Write channel */
                                if (msg_bufno >= channel->num_wr_buffers) {
-                                       malformed_message(&buf[i]);
+                                       malformed_message(ep, &buf[i]);
                                        break;
                                }
                                spin_lock(&channel->wr_spinlock);
@@ -221,7 +221,7 @@ irqreturn_t xillybus_isr(int irq, void *data)
                                /* Read channel */
 
                                if (msg_bufno >= channel->num_rd_buffers) {
-                                       malformed_message(&buf[i]);
+                                       malformed_message(ep, &buf[i]);
                                        break;
                                }
 
@@ -243,14 +243,14 @@ irqreturn_t xillybus_isr(int irq, void *data)
                        if ((msg_channel > ep->num_channels) ||
                            (msg_channel == 0) || (!msg_dir) ||
                            !ep->channels[msg_channel]->wr_supports_nonempty) {
-                               malformed_message(&buf[i]);
+                               malformed_message(ep, &buf[i]);
                                break;
                        }
 
                        channel = ep->channels[msg_channel];
 
                        if (msg_bufno >= channel->num_wr_buffers) {
-                               malformed_message(&buf[i]);
+                               malformed_message(ep, &buf[i]);
                                break;
                        }
                        spin_lock(&channel->wr_spinlock);
@@ -283,16 +283,11 @@ irqreturn_t xillybus_isr(int irq, void *data)
                case XILLYMSG_OPCODE_FATAL_ERROR:
                        ep->fatal_error = 1;
                        wake_up_interruptible(&ep->ep_wait); /* For select() */
-                       pr_err("xillybus: FPGA reported a fatal "
-                              "error. This means that the low-level "
-                              "communication with the device has failed. "
-                              "This hardware problem is most likely "
-                              "unrelated to xillybus (neither kernel "
-                              "module nor FPGA core), but reports are "
-                              "still welcome. All I/O is aborted.\n");
+                       dev_err(ep->dev,
+                               "FPGA reported a fatal error. This means that the low-level communication with the device has failed. This hardware problem is most likely unrelated to Xillybus (neither kernel module nor FPGA core), but reports are still welcome. All I/O is aborted.\n");
                        break;
                default:
-                       malformed_message(&buf[i]);
+                       malformed_message(ep, &buf[i]);
                        break;
                }
        }
@@ -486,8 +481,8 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
 
                if ((channelnum > ep->num_channels) ||
                    ((channelnum == 0) && !is_writebuf)) {
-                       pr_err("xillybus: IDT requests channel out "
-                              "of range. Aborting.\n");
+                       dev_err(ep->dev,
+                               "IDT requests channel out of range. Aborting.\n");
                        return -ENODEV;
                }
 
@@ -565,9 +560,8 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
                                 */
                                if ((left_of_wr_salami < bytebufsize) &&
                                    (left_of_wr_salami > 0)) {
-                                       pr_err("xillybus: "
-                                              "Corrupt buffer allocation "
-                                              "in IDT. Aborting.\n");
+                                       dev_err(ep->dev,
+                                               "Corrupt buffer allocation in IDT. Aborting.\n");
                                        return -ENODEV;
                                }
 
@@ -644,9 +638,8 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
                                 */
                                if ((left_of_rd_salami < bytebufsize) &&
                                    (left_of_rd_salami > 0)) {
-                                       pr_err("xillybus: "
-                                              "Corrupt buffer allocation "
-                                              "in IDT. Aborting.\n");
+                                       dev_err(ep->dev,
+                                               "Corrupt buffer allocation in IDT. Aborting.\n");
                                        return -ENODEV;
                                }
 
@@ -706,19 +699,19 @@ static int xilly_setupchannels(struct xilly_endpoint *ep,
        }
 
        if (!msg_buf_done) {
-               pr_err("xillybus: Corrupt IDT: No message buffer. "
-                      "Aborting.\n");
+               dev_err(ep->dev,
+                       "Corrupt IDT: No message buffer. Aborting.\n");
                return -ENODEV;
        }
 
        return 0;
 
 memfail:
-       pr_err("xillybus: Failed to allocate write buffer memory. "
-              "Aborting.\n");
+       dev_err(ep->dev,
+               "Failed to allocate write buffer memory. Aborting.\n");
        return -ENOMEM;
 dmafail:
-       pr_err("xillybus: Failed to map DMA memory!. Aborting.\n");
+       dev_err(ep->dev, "Failed to map DMA memory!. Aborting.\n");
        return -ENOMEM;
 }
 
@@ -745,8 +738,8 @@ static void xilly_scan_idt(struct xilly_endpoint *endpoint,
        scan++;
 
        if (scan > end_of_idt) {
-               pr_err("xillybus: IDT device name list overflow. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "IDT device name list overflow. Aborting.\n");
                idt_handle->chandesc = NULL;
                return;
        } else
@@ -757,8 +750,8 @@ static void xilly_scan_idt(struct xilly_endpoint *endpoint,
        if (len & 0x03) {
                idt_handle->chandesc = NULL;
 
-               pr_err("xillybus: Corrupt IDT device name list. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Corrupt IDT device name list. Aborting.\n");
        }
 
        idt_handle->entries = len >> 2;
@@ -787,7 +780,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
                                         XILLY_TIMEOUT);
 
        if (channel->wr_sleepy) {
-               pr_err("xillybus: Failed to obtain IDT. Aborting.\n");
+               dev_err(endpoint->dev, "Failed to obtain IDT. Aborting.\n");
 
                if (endpoint->fatal_error)
                        return -EIO;
@@ -803,8 +796,8 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
                DMA_FROM_DEVICE);
 
        if (channel->wr_buffers[0]->end_offset != endpoint->idtlen) {
-               pr_err("xillybus: IDT length mismatch (%d != %d). "
-                      "Aborting.\n",
+               dev_err(endpoint->dev,
+                       "IDT length mismatch (%d != %d). Aborting.\n",
                       channel->wr_buffers[0]->end_offset, endpoint->idtlen);
                rc = -ENODEV;
                return rc;
@@ -812,7 +805,7 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
 
        if (crc32_le(~0, channel->wr_buffers[0]->addr,
                     endpoint->idtlen+1) != 0) {
-               pr_err("xillybus: IDT failed CRC check. Aborting.\n");
+               dev_err(endpoint->dev, "IDT failed CRC check. Aborting.\n");
                rc = -ENODEV;
                return rc;
        }
@@ -821,9 +814,8 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
 
        /* Check version number. Accept anything below 0x82 for now. */
        if (*version > 0x82) {
-               pr_err("xillybus: No support for IDT version 0x%02x. "
-                      "Maybe the xillybus driver needs an upgarde. "
-                      "Aborting.\n",
+               dev_err(endpoint->dev,
+                       "No support for IDT version 0x%02x. Maybe the xillybus driver needs an upgarde. Aborting.\n",
                       (int) *version);
                rc = -ENODEV;
                return rc;
@@ -1312,9 +1304,8 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout)
                                 channel->rd_wait,
                                 (!channel->rd_full),
                                 timeout) == 0) {
-                       pr_warn("xillybus: "
-                               "Timed out while flushing. "
-                               "Output data may be lost.\n");
+                       dev_warn(channel->endpoint->dev,
+                               "Timed out while flushing. Output data may be lost.\n");
 
                        rc = -ETIMEDOUT;
                        break;
@@ -1354,12 +1345,11 @@ static void xillybus_autoflush(struct work_struct *work)
        rc = xillybus_myflush(channel, -1);
 
        if (rc == -EINTR)
-               pr_warn("xillybus: Autoflush failed because "
-                       "work queue thread got a signal.\n");
+               dev_warn(channel->endpoint->dev,
+                        "Autoflush failed because work queue thread got a signal.\n");
        else if (rc)
-               pr_err("xillybus: Autoflush failed under "
-                      "weird circumstances.\n");
-
+               dev_err(channel->endpoint->dev,
+                       "Autoflush failed under weird circumstances.\n");
 }
 
 static ssize_t xillybus_write(struct file *filp, const char __user *userbuf,
@@ -1615,8 +1605,8 @@ static int xillybus_open(struct inode *inode, struct file *filp)
        mutex_unlock(&ep_list_lock);
 
        if (!endpoint) {
-               pr_err("xillybus: open() failed to find a device "
-                      "for major=%d and minor=%d\n", major, minor);
+               pr_err("xillybus: open() failed to find a device for major=%d and minor=%d\n",
+                      major, minor);
                return -ENODEV;
        }
 
@@ -1642,15 +1632,15 @@ static int xillybus_open(struct inode *inode, struct file *filp)
        if ((filp->f_mode & FMODE_READ) && (filp->f_flags & O_NONBLOCK) &&
            (channel->wr_synchronous || !channel->wr_allow_partial ||
             !channel->wr_supports_nonempty)) {
-               pr_err("xillybus: open() failed: "
-                      "O_NONBLOCK not allowed for read on this device\n");
+               dev_err(endpoint->dev,
+                       "open() failed: O_NONBLOCK not allowed for read on this device\n");
                return -ENODEV;
        }
 
        if ((filp->f_mode & FMODE_WRITE) && (filp->f_flags & O_NONBLOCK) &&
            (channel->rd_synchronous || !channel->rd_allow_partial)) {
-               pr_err("xillybus: open() failed: "
-                      "O_NONBLOCK not allowed for write on this device\n");
+               dev_err(endpoint->dev,
+                       "open() failed: O_NONBLOCK not allowed for write on this device\n");
                return -ENODEV;
        }
 
@@ -1765,8 +1755,8 @@ static int xillybus_release(struct inode *inode, struct file *filp)
                rc = mutex_lock_interruptible(&channel->rd_mutex);
 
                if (rc) {
-                       pr_warn("xillybus: Failed to close file. "
-                               "Hardware left in messy state.\n");
+                       dev_warn(channel->endpoint->dev,
+                                "Failed to close file. Hardware left in messy state.\n");
                        return rc;
                }
 
@@ -1791,8 +1781,8 @@ static int xillybus_release(struct inode *inode, struct file *filp)
        if (filp->f_mode & FMODE_READ) {
                rc = mutex_lock_interruptible(&channel->wr_mutex);
                if (rc) {
-                       pr_warn("xillybus: Failed to close file. "
-                               "Hardware left in messy state.\n");
+                       dev_warn(channel->endpoint->dev,
+                                "Failed to close file. Hardware left in messy state.\n");
                        return rc;
                }
 
@@ -1853,10 +1843,8 @@ static int xillybus_release(struct inode *inode, struct file *filp)
 
                                if (channel->wr_sleepy) {
                                        mutex_unlock(&channel->wr_mutex);
-                                       pr_warn("xillybus: Hardware failed to "
-                                               "respond to close command, "
-                                               "therefore left in "
-                                               "messy state.\n");
+                                       dev_warn(channel->endpoint->dev,
+                                                "Hardware failed to respond to close command, therefore left in messy state.\n");
                                        return -EINTR;
                                }
                        }
@@ -2022,7 +2010,7 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint,
                                 xillyname);
 
        if (rc) {
-               pr_warn("xillybus: Failed to obtain major/minors");
+               dev_warn(endpoint->dev, "Failed to obtain major/minors");
                goto error1;
        }
 
@@ -2034,7 +2022,7 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint,
        rc = cdev_add(&endpoint->cdev, MKDEV(major, minor),
                      endpoint->num_channels);
        if (rc) {
-               pr_warn("xillybus: Failed to add cdev. Aborting.\n");
+               dev_warn(endpoint->dev, "Failed to add cdev. Aborting.\n");
                goto error2;
        }
 
@@ -2057,14 +2045,15 @@ static int xillybus_init_chrdev(struct xilly_endpoint *endpoint,
                                       "%s", devname);
 
                if (IS_ERR(device)) {
-                       pr_warn("xillybus: Failed to create %s "
-                               "device. Aborting.\n", devname);
+                       dev_warn(endpoint->dev,
+                                "Failed to create %s device. Aborting.\n",
+                                devname);
                        goto error3;
                }
        }
 
-       pr_info("xillybus: Created %d device files.\n",
-               endpoint->num_channels);
+       dev_info(endpoint->dev, "Created %d device files.\n",
+                endpoint->num_channels);
        return 0; /* succeed */
 
 error3:
@@ -2093,8 +2082,8 @@ static void xillybus_cleanup_chrdev(struct xilly_endpoint *endpoint)
                                       endpoint->lowest_minor),
                                 endpoint->num_channels);
 
-       pr_info("xillybus: Removed %d device files.\n",
-               endpoint->num_channels);
+       dev_info(endpoint->dev, "Removed %d device files.\n",
+                endpoint->num_channels);
 }
 
 
@@ -2107,7 +2096,7 @@ struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
 
        endpoint = kzalloc(sizeof(*endpoint), GFP_KERNEL);
        if (!endpoint) {
-               pr_err("xillybus: Failed to allocate memory. Aborting.\n");
+               dev_err(dev, "Failed to allocate memory. Aborting.\n");
                return NULL;
        }
 
@@ -2141,8 +2130,8 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint)
                                         XILLY_TIMEOUT);
 
        if (endpoint->idtlen < 0) {
-               pr_err("xillybus: Failed to quiesce the device on "
-                      "exit. Quitting while leaving a mess.\n");
+               dev_err(endpoint->dev,
+                       "Failed to quiesce the device on exit. Quitting while leaving a mess.\n");
                return -ENODEV;
        }
        return 0; /* Success */
@@ -2209,7 +2198,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
                                         XILLY_TIMEOUT);
 
        if (endpoint->idtlen < 0) {
-               pr_err("xillybus: No response from FPGA. Aborting.\n");
+               dev_err(endpoint->dev, "No response from FPGA. Aborting.\n");
                rc = -ENODEV;
                goto failed_quiesce;
        }
@@ -2323,7 +2312,7 @@ static int __init xillybus_init(void)
        xillybus_class = class_create(THIS_MODULE, xillyname);
        if (IS_ERR(xillybus_class)) {
                rc = PTR_ERR(xillybus_class);
-               pr_warn("xillybus: Failed to register class xillybus\n");
+               pr_warn("Failed to register class xillybus\n");
 
                return rc;
        }
index 92c2931f434840435a90327e6d7e66c30dde6ad4..394bfea1af6e308d0118e75adc16d25bc0dc801d 100644 (file)
@@ -117,14 +117,15 @@ static int xilly_drv_probe(struct platform_device *op)
 
        rc = of_address_to_resource(dev->of_node, 0, &endpoint->res);
        if (rc) {
-               pr_warn("xillybus: Failed to obtain device tree "
-                       "resource\n");
+               dev_warn(endpoint->dev,
+                        "Failed to obtain device tree resource\n");
                goto failed_request_regions;
        }
 
        if  (!request_mem_region(endpoint->res.start,
                                 resource_size(&endpoint->res), xillyname)) {
-               pr_err("xillybus: request_mem_region failed. Aborting.\n");
+               dev_err(endpoint->dev,
+                       "request_mem_region failed. Aborting.\n");
                rc = -EBUSY;
                goto failed_request_regions;
        }
@@ -132,7 +133,8 @@ static int xilly_drv_probe(struct platform_device *op)
        endpoint->registers = of_iomap(dev->of_node, 0);
 
        if (!endpoint->registers) {
-               pr_err("xillybus: Failed to map I/O memory. Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Failed to map I/O memory. Aborting.\n");
                goto failed_iomap0;
        }
 
@@ -141,8 +143,8 @@ static int xilly_drv_probe(struct platform_device *op)
        rc = request_irq(irq, xillybus_isr, 0, xillyname, endpoint);
 
        if (rc) {
-               pr_err("xillybus: Failed to register IRQ handler. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Failed to register IRQ handler. Aborting.\n");
                rc = -ENODEV;
                goto failed_register_irq;
        }
@@ -198,15 +200,4 @@ static struct platform_driver xillybus_platform_driver = {
        },
 };
 
-static int __init xillybus_of_init(void)
-{
-       return platform_driver_register(&xillybus_platform_driver);
-}
-
-static void __exit xillybus_of_exit(void)
-{
-       platform_driver_unregister(&xillybus_platform_driver);
-}
-
-module_init(xillybus_of_init);
-module_exit(xillybus_of_exit);
+module_platform_driver(xillybus_platform_driver);
index 67013652358b905039bbfae37791cb721baf7352..1811aa76421384aedf3e47eb62e8e60e0ea6b6b4 100644 (file)
@@ -134,7 +134,7 @@ static int xilly_probe(struct pci_dev *pdev,
        struct xilly_endpoint *endpoint;
        int rc = 0;
 
-       endpoint = xillybus_init_endpoint(pdev, NULL, &pci_hw);
+       endpoint = xillybus_init_endpoint(pdev, &pdev->dev, &pci_hw);
 
        if (!endpoint)
                return -ENOMEM;
@@ -148,29 +148,29 @@ static int xilly_probe(struct pci_dev *pdev,
        pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
 
        if (rc) {
-               pr_err("xillybus: pci_enable_device() failed. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "pci_enable_device() failed. Aborting.\n");
                goto no_enable;
        }
 
        if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-               pr_err("xillybus: Incorrect BAR configuration. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Incorrect BAR configuration. Aborting.\n");
                rc = -ENODEV;
                goto bad_bar;
        }
 
        rc = pci_request_regions(pdev, xillyname);
        if (rc) {
-               pr_err("xillybus: pci_request_regions() failed. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "pci_request_regions() failed. Aborting.\n");
                goto failed_request_regions;
        }
 
        endpoint->registers = pci_iomap(pdev, 0, 128);
 
        if (!endpoint->registers) {
-               pr_err("xillybus: Failed to map BAR 0. Aborting.\n");
+               dev_err(endpoint->dev, "Failed to map BAR 0. Aborting.\n");
                goto failed_iomap0;
        }
 
@@ -178,16 +178,16 @@ static int xilly_probe(struct pci_dev *pdev,
 
        /* Set up a single MSI interrupt */
        if (pci_enable_msi(pdev)) {
-               pr_err("xillybus: Failed to enable MSI interrupts. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Failed to enable MSI interrupts. Aborting.\n");
                rc = -ENODEV;
                goto failed_enable_msi;
        }
        rc = request_irq(pdev->irq, xillybus_isr, 0, xillyname, endpoint);
 
        if (rc) {
-               pr_err("xillybus: Failed to register MSI handler. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev,
+                       "Failed to register MSI handler. Aborting.\n");
                rc = -ENODEV;
                goto failed_register_msi;
        }
@@ -202,8 +202,7 @@ static int xilly_probe(struct pci_dev *pdev,
        if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
                endpoint->dma_using_dac = 0;
        else {
-               pr_err("xillybus: Failed to set DMA mask. "
-                      "Aborting.\n");
+               dev_err(endpoint->dev, "Failed to set DMA mask. Aborting.\n");
                rc = -ENODEV;
                goto failed_dmamask;
        }
index 7fab032298f33986cd55b518d3db60eebadb4d9b..0ae13cd0908ed0b25341b812993bea65f681e45f 100644 (file)
@@ -1,5 +1,6 @@
 config ZSMALLOC
        bool "Memory allocator for compressed pages"
+       depends on MMU
        default n
        help
          zsmalloc is a slab-based memory allocator designed to store
index 32ba45158d39eaf050adfc411118163f23858b4f..a265af294ea49a28c0384af71aa5ee1a249b3be8 100644 (file)
@@ -47,11 +47,13 @@ struct hid_sensor_hub_attribute_info {
  * @hdev:              Stores the hid instance.
  * @vendor_id:         Vendor id of hub device.
  * @product_id:                Product id of hub device.
+ * @ref_cnt:           Number of MFD clients have opened this device
  */
 struct hid_sensor_hub_device {
        struct hid_device *hdev;
        u32 vendor_id;
        u32 product_id;
+       int ref_cnt;
 };
 
 /**
@@ -74,6 +76,22 @@ struct hid_sensor_hub_callbacks {
                         void *priv);
 };
 
+/**
+* sensor_hub_device_open() - Open hub device
+* @hsdev:      Hub device instance.
+*
+* Used to open hid device for sensor hub.
+*/
+int sensor_hub_device_open(struct hid_sensor_hub_device *hsdev);
+
+/**
+* sensor_hub_device_clode() - Close hub device
+* @hsdev:      Hub device instance.
+*
+* Used to clode hid device for sensor hub.
+*/
+void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev);
+
 /* Registration functions */
 
 /**
index 2bac0eb8948df6c541d738823aaeb37153b018e0..15607b45221a9b9c03c6fdaade48afd9a4641c9e 100644 (file)
@@ -11,6 +11,7 @@
 #define _IIO_BUFFER_GENERIC_H_
 #include <linux/sysfs.h>
 #include <linux/iio/iio.h>
+#include <linux/kref.h>
 
 #ifdef CONFIG_IIO_BUFFER
 
@@ -26,6 +27,8 @@ struct iio_buffer;
  * @set_bytes_per_datum:set number of bytes per datum
  * @get_length:                get number of datums in buffer
  * @set_length:                set number of datums in buffer
+ * @release:           called when the last reference to the buffer is dropped,
+ *                     should free all resources allocated by the buffer.
  *
  * The purpose of this structure is to make the buffer element
  * modular as event for a given driver, different usecases may require
@@ -36,7 +39,7 @@ struct iio_buffer;
  * any of them not existing.
  **/
 struct iio_buffer_access_funcs {
-       int (*store_to)(struct iio_buffer *buffer, u8 *data);
+       int (*store_to)(struct iio_buffer *buffer, const void *data);
        int (*read_first_n)(struct iio_buffer *buffer,
                            size_t n,
                            char __user *buf);
@@ -47,6 +50,8 @@ struct iio_buffer_access_funcs {
        int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
        int (*get_length)(struct iio_buffer *buffer);
        int (*set_length)(struct iio_buffer *buffer, int length);
+
+       void (*release)(struct iio_buffer *buffer);
 };
 
 /**
@@ -67,6 +72,7 @@ struct iio_buffer_access_funcs {
  * @demux_list:                [INTERN] list of operations required to demux the scan.
  * @demux_bounce:      [INTERN] buffer for doing gather from incoming scan.
  * @buffer_list:       [INTERN] entry in the devices list of current buffers.
+ * @ref:               [INTERN] reference count of the buffer.
  */
 struct iio_buffer {
        int                                     length;
@@ -81,8 +87,9 @@ struct iio_buffer {
        bool                                    stufftoread;
        const struct attribute_group *attrs;
        struct list_head                        demux_list;
-       unsigned char                           *demux_bounce;
+       void                                    *demux_bounce;
        struct list_head                        buffer_list;
+       struct kref                             ref;
 };
 
 /**
@@ -120,7 +127,32 @@ int iio_scan_mask_set(struct iio_dev *indio_dev,
  * @indio_dev:         iio_dev structure for device.
  * @data:              Full scan.
  */
-int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data);
+int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data);
+
+/*
+ * iio_push_to_buffers_with_timestamp() - push data and timestamp to buffers
+ * @indio_dev:         iio_dev structure for device.
+ * @data:              sample data
+ * @timestamp:         timestamp for the sample data
+ *
+ * Pushes data to the IIO device's buffers. If timestamps are enabled for the
+ * device the function will store the supplied timestamp as the last element in
+ * the sample data buffer before pushing it to the device buffers. The sample
+ * data buffer needs to be large enough to hold the additional timestamp
+ * (usually the buffer should be indio->scan_bytes bytes large).
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ */
+static inline int iio_push_to_buffers_with_timestamp(struct iio_dev *indio_dev,
+       void *data, int64_t timestamp)
+{
+       if (indio_dev->scan_timestamp) {
+               size_t ts_offset = indio_dev->scan_bytes / sizeof(int64_t) - 1;
+               ((int64_t *)data)[ts_offset] = timestamp;
+       }
+
+       return iio_push_to_buffers(indio_dev, data);
+}
 
 int iio_update_demux(struct iio_dev *indio_dev);
 
@@ -174,11 +206,27 @@ ssize_t iio_buffer_show_enable(struct device *dev,
                                           iio_buffer_show_enable,      \
                                           iio_buffer_store_enable)
 
-int iio_sw_buffer_preenable(struct iio_dev *indio_dev);
-
 bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
        const unsigned long *mask);
 
+struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer);
+void iio_buffer_put(struct iio_buffer *buffer);
+
+/**
+ * iio_device_attach_buffer - Attach a buffer to a IIO device
+ * @indio_dev: The device the buffer should be attached to
+ * @buffer: The buffer to attach to the device
+ *
+ * This function attaches a buffer to a IIO device. The buffer stays attached to
+ * the device until the device is freed. The function should only be called at
+ * most once per device.
+ */
+static inline void iio_device_attach_buffer(struct iio_dev *indio_dev,
+       struct iio_buffer *buffer)
+{
+       indio_dev->buffer = iio_buffer_get(buffer);
+}
+
 #else /* CONFIG_IIO_BUFFER */
 
 static inline int iio_buffer_register(struct iio_dev *indio_dev,
@@ -191,6 +239,9 @@ static inline int iio_buffer_register(struct iio_dev *indio_dev,
 static inline void iio_buffer_unregister(struct iio_dev *indio_dev)
 {}
 
+static inline void iio_buffer_get(struct iio_buffer *buffer) {}
+static inline void iio_buffer_put(struct iio_buffer *buffer) {}
+
 #endif /* CONFIG_IIO_BUFFER */
 
 #endif /* _IIO_BUFFER_GENERIC_H_ */
index e51f65480ea5a895828433444e0d3ec6348ca785..3c005eb3a0a4bab608479bd3ba7cd4d3dc65cd5f 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/irqreturn.h>
 #include <linux/iio/trigger.h>
 #include <linux/bitops.h>
+#include <linux/regulator/consumer.h>
 
 #include <linux/platform_data/st_sensors_pdata.h>
 
@@ -184,6 +185,7 @@ struct st_sensors {
        u8 wai;
        char sensors_supported[ST_SENSORS_MAX_4WAI][ST_SENSORS_MAX_NAME];
        struct iio_chan_spec *ch;
+       int num_ch;
        struct st_sensor_odr odr;
        struct st_sensor_power pw;
        struct st_sensor_axis enable_axis;
@@ -200,6 +202,8 @@ struct st_sensors {
  * @trig: The trigger in use by the core driver.
  * @sensor: Pointer to the current sensor struct in use.
  * @current_fullscale: Maximum range of measure by the sensor.
+ * @vdd: Pointer to sensor's Vdd power supply
+ * @vdd_io: Pointer to sensor's Vdd-IO power supply
  * @enabled: Status of the sensor (false->off, true->on).
  * @multiread_bit: Use or not particular bit for [I2C/SPI] multiread.
  * @buffer_data: Data used by buffer part.
@@ -215,6 +219,8 @@ struct st_sensor_data {
        struct iio_trigger *trig;
        struct st_sensors *sensor;
        struct st_sensor_fullscale_avl *current_fullscale;
+       struct regulator *vdd;
+       struct regulator *vdd_io;
 
        bool enabled;
        bool multiread_bit;
index 833926c91aa84dff36403b814a046267dd968557..2752b1fd12be3ea8b41c58f64b408d88f1afddaa 100644 (file)
@@ -77,7 +77,7 @@ struct iio_cb_buffer;
  * fail.
  */
 struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
-                                            int (*cb)(u8 *data,
+                                            int (*cb)(const void *data,
                                                       void *private),
                                             void *private);
 /**
index 13ce220c70036f077b7c8ec28134d5d44c9a4eb4..5dab2c41031f059cce67944a0eea559a9e09bede 100644 (file)
@@ -26,20 +26,6 @@ struct iio_event_data {
 
 #define IIO_GET_EVENT_FD_IOCTL _IOR('i', 0x90, int)
 
-enum iio_event_type {
-       IIO_EV_TYPE_THRESH,
-       IIO_EV_TYPE_MAG,
-       IIO_EV_TYPE_ROC,
-       IIO_EV_TYPE_THRESH_ADAPTIVE,
-       IIO_EV_TYPE_MAG_ADAPTIVE,
-};
-
-enum iio_event_direction {
-       IIO_EV_DIR_EITHER,
-       IIO_EV_DIR_RISING,
-       IIO_EV_DIR_FALLING,
-};
-
 /**
  * IIO_EVENT_CODE() - create event identifier
  * @chan_type: Type of the channel. Should be one of enum iio_chan_type.
index 2103cc32a5fb9b7d701d428e2f49ac636bbc6376..256a90a1bea681fde6473e2d5d74bc93ea868a87 100644 (file)
@@ -36,6 +36,14 @@ enum iio_chan_info_enum {
        IIO_CHAN_INFO_PHASE,
        IIO_CHAN_INFO_HARDWAREGAIN,
        IIO_CHAN_INFO_HYSTERESIS,
+       IIO_CHAN_INFO_INT_TIME,
+};
+
+enum iio_shared_by {
+       IIO_SEPARATE,
+       IIO_SHARED_BY_TYPE,
+       IIO_SHARED_BY_DIR,
+       IIO_SHARED_BY_ALL
 };
 
 enum iio_endian {
@@ -57,7 +65,7 @@ struct iio_dev;
  */
 struct iio_chan_spec_ext_info {
        const char *name;
-       bool shared;
+       enum iio_shared_by shared;
        ssize_t (*read)(struct iio_dev *, uintptr_t private,
                        struct iio_chan_spec const *, char *buf);
        ssize_t (*write)(struct iio_dev *, uintptr_t private,
@@ -125,11 +133,34 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,
 #define IIO_ENUM_AVAILABLE(_name, _e) \
 { \
        .name = (_name "_available"), \
-       .shared = true, \
+       .shared = IIO_SHARED_BY_TYPE, \
        .read = iio_enum_available_read, \
        .private = (uintptr_t)(_e), \
 }
 
+/**
+ * struct iio_event_spec - specification for a channel event
+ * @type:                  Type of the event
+ * @dir:                   Direction of the event
+ * @mask_separate:         Bit mask of enum iio_event_info values. Attributes
+ *                         set in this mask will be registered per channel.
+ * @mask_shared_by_type:    Bit mask of enum iio_event_info values. Attributes
+ *                         set in this mask will be shared by channel type.
+ * @mask_shared_by_dir:            Bit mask of enum iio_event_info values. Attributes
+ *                         set in this mask will be shared by channel type and
+ *                         direction.
+ * @mask_shared_by_all:            Bit mask of enum iio_event_info values. Attributes
+ *                         set in this mask will be shared by all channels.
+ */
+struct iio_event_spec {
+       enum iio_event_type type;
+       enum iio_event_direction dir;
+       unsigned long mask_separate;
+       unsigned long mask_shared_by_type;
+       unsigned long mask_shared_by_dir;
+       unsigned long mask_shared_by_all;
+};
+
 /**
  * struct iio_chan_spec - specification of a single channel
  * @type:              What type of measurement is the channel making.
@@ -146,13 +177,18 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,
  *                     shift:          Shift right by this before masking out
  *                                     realbits.
  *                     endianness:     little or big endian
- * @info_mask:         What information is to be exported about this channel.
- *                     This includes calibbias, scale etc.
  * @info_mask_separate: What information is to be exported that is specific to
  *                     this channel.
  * @info_mask_shared_by_type: What information is to be exported that is shared
-*                      by all channels of the same type.
+ *                     by all channels of the same type.
+ * @info_mask_shared_by_dir: What information is to be exported that is shared
+ *                     by all channels of the same direction.
+ * @info_mask_shared_by_all: What information is to be exported that is shared
+ *                     by all channels.
  * @event_mask:                What events can this channel produce.
+ * @event_spec:                Array of events which should be registered for this
+ *                     channel.
+ * @num_event_specs:   Size of the event_spec array.
  * @ext_info:          Array of extended info attributes for this channel.
  *                     The array is NULL terminated, the last element should
  *                     have its name field set to NULL.
@@ -186,10 +222,13 @@ struct iio_chan_spec {
                u8      shift;
                enum iio_endian endianness;
        } scan_type;
-       long                    info_mask;
        long                    info_mask_separate;
        long                    info_mask_shared_by_type;
+       long                    info_mask_shared_by_dir;
+       long                    info_mask_shared_by_all;
        long                    event_mask;
+       const struct iio_event_spec *event_spec;
+       unsigned int            num_event_specs;
        const struct iio_chan_spec_ext_info *ext_info;
        const char              *extend_name;
        const char              *datasheet_name;
@@ -212,7 +251,9 @@ static inline bool iio_channel_has_info(const struct iio_chan_spec *chan,
        enum iio_chan_info_enum type)
 {
        return (chan->info_mask_separate & BIT(type)) |
-              (chan->info_mask_shared_by_type & BIT(type));
+               (chan->info_mask_shared_by_type & BIT(type)) |
+               (chan->info_mask_shared_by_dir & BIT(type)) |
+               (chan->info_mask_shared_by_all & BIT(type));
 }
 
 #define IIO_ST(si, rb, sb, sh)                                         \
@@ -270,6 +311,12 @@ struct iio_dev;
  *                     is event dependant. event_code specifies which event.
  * @write_event_value: write the value associated with the event.
  *                     Meaning is event dependent.
+ * @read_event_config_new: find out if the event is enabled. New style interface.
+ * @write_event_config_new: set if the event is enabled. New style interface.
+ * @read_event_value_new: read a configuration value associated with the event.
+ *                         New style interface.
+ * @write_event_value_new: write a configuration value for the event. New style
+ *                        interface.
  * @validate_trigger:  function to validate the trigger when the
  *                     current trigger gets changed.
  * @update_scan_mode:  function to configure device and scan buffer when
@@ -310,6 +357,30 @@ struct iio_info {
        int (*write_event_value)(struct iio_dev *indio_dev,
                                 u64 event_code,
                                 int val);
+
+       int (*read_event_config_new)(struct iio_dev *indio_dev,
+                                const struct iio_chan_spec *chan,
+                                enum iio_event_type type,
+                                enum iio_event_direction dir);
+
+       int (*write_event_config_new)(struct iio_dev *indio_dev,
+                                 const struct iio_chan_spec *chan,
+                                 enum iio_event_type type,
+                                 enum iio_event_direction dir,
+                                 int state);
+
+       int (*read_event_value_new)(struct iio_dev *indio_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);
+
+       int (*write_event_value_new)(struct iio_dev *indio_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);
+
        int (*validate_trigger)(struct iio_dev *indio_dev,
                                struct iio_trigger *trig);
        int (*update_scan_mode)(struct iio_dev *indio_dev,
@@ -457,7 +528,7 @@ static inline void iio_device_put(struct iio_dev *indio_dev)
 {
        if (indio_dev)
                put_device(&indio_dev->dev);
-};
+}
 
 /**
  * dev_to_iio_dev() - Get IIO device struct from a device struct
@@ -593,7 +664,7 @@ static inline bool iio_buffer_enabled(struct iio_dev *indio_dev)
 {
        return indio_dev->currentmode
                & (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE);
-};
+}
 
 /**
  * iio_get_debugfs_dentry() - helper function to get the debugfs_dentry
@@ -603,12 +674,12 @@ static inline bool iio_buffer_enabled(struct iio_dev *indio_dev)
 static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev)
 {
        return indio_dev->debugfs_dentry;
-};
+}
 #else
 static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev)
 {
        return NULL;
-};
+}
 #endif
 
 int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer,
index 2958c960003a7ed3bcb22baf8ca02266f3736c7d..8a1d18640ab94dd7d29ddec3473f3c5c0e9ef112 100644 (file)
@@ -100,6 +100,21 @@ struct iio_const_attr {
 #define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string)                        \
        IIO_CONST_ATTR(sampling_frequency_available, _string)
 
+/**
+ * IIO_DEV_ATTR_INT_TIME_AVAIL - list available integration times
+ * @_show: output method for the attribute
+ **/
+#define IIO_DEV_ATTR_INT_TIME_AVAIL(_show)             \
+       IIO_DEVICE_ATTR(integration_time_available, S_IRUGO, _show, NULL, 0)
+/**
+ * IIO_CONST_ATTR_INT_TIME_AVAIL - list available integration times
+ * @_string: frequency string for the attribute
+ *
+ * Constant version
+ **/
+#define IIO_CONST_ATTR_INT_TIME_AVAIL(_string)         \
+       IIO_CONST_ATTR(integration_time_available, _string)
+
 #define IIO_DEV_ATTR_TEMP_RAW(_show)                   \
        IIO_DEVICE_ATTR(in_temp_raw, S_IRUGO, _show, NULL, 0)
 
index 88bf0f0d27b4a973b6b211b06ececfd294c82c4c..4ac928ee31c5e4c59c03de6aff936190168bb1f2 100644 (file)
@@ -54,6 +54,26 @@ enum iio_modifier {
        IIO_MOD_LIGHT_BLUE,
 };
 
+enum iio_event_type {
+       IIO_EV_TYPE_THRESH,
+       IIO_EV_TYPE_MAG,
+       IIO_EV_TYPE_ROC,
+       IIO_EV_TYPE_THRESH_ADAPTIVE,
+       IIO_EV_TYPE_MAG_ADAPTIVE,
+};
+
+enum iio_event_info {
+       IIO_EV_INFO_ENABLE,
+       IIO_EV_INFO_VALUE,
+       IIO_EV_INFO_HYSTERESIS,
+};
+
+enum iio_event_direction {
+       IIO_EV_DIR_EITHER,
+       IIO_EV_DIR_RISING,
+       IIO_EV_DIR_FALLING,
+};
+
 #define IIO_VAL_INT 1
 #define IIO_VAL_INT_PLUS_MICRO 2
 #define IIO_VAL_INT_PLUS_NANO 3
index 7b68a061cd60f8df9bf64441576f304870bf660f..d498d98f0c2cbfd3c9076aa439433a23caa80899 100644 (file)
 /* Step Enable */
 #define STEPENB_MASK           (0x1FFFF << 0)
 #define STEPENB(val)           ((val) << 0)
+#define ENB(val)                       (1 << (val))
+#define STPENB_STEPENB         STEPENB(0x1FFFF)
+#define STPENB_STEPENB_TC      STEPENB(0x1FFF)
 
 /* IRQ enable */
 #define IRQENB_HW_PEN          BIT(0)
 #define IRQENB_FIFO0THRES      BIT(2)
+#define IRQENB_FIFO0OVRRUN     BIT(3)
+#define IRQENB_FIFO0UNDRFLW    BIT(4)
 #define IRQENB_FIFO1THRES      BIT(5)
+#define IRQENB_FIFO1OVRRUN     BIT(6)
+#define IRQENB_FIFO1UNDRFLW    BIT(7)
 #define IRQENB_PENUP           BIT(9)
 
 /* Step Configuration */
 #define STEPCONFIG_MODE_MASK   (3 << 0)
 #define STEPCONFIG_MODE(val)   ((val) << 0)
+#define STEPCONFIG_MODE_SWCNT  STEPCONFIG_MODE(1)
 #define STEPCONFIG_MODE_HWSYNC STEPCONFIG_MODE(2)
 #define STEPCONFIG_AVG_MASK    (7 << 2)
 #define STEPCONFIG_AVG(val)    ((val) << 2)
 #define ADC_CLK                        3000000
 #define TOTAL_STEPS            16
 #define TOTAL_CHANNELS         8
+#define FIFO1_THRESHOLD                19
 
 /*
  * time in us for processing a single channel, calculated as follows: