summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--system/AnonymousPro/AnonymousPro.SlackBuild14
-rw-r--r--system/AnonymousPro/AnonymousPro.info8
-rw-r--r--system/AnonymousPro/doinst.sh12
-rw-r--r--system/Iosevka-slab/Iosevka-slab.SlackBuild2
-rw-r--r--system/Iosevka-slab/Iosevka-slab.info6
-rw-r--r--system/Iosevka/Iosevka.SlackBuild2
-rw-r--r--system/Iosevka/Iosevka.info6
-rw-r--r--system/Sl/Sl.SlackBuild3
-rw-r--r--system/Sl/Sl.info4
-rw-r--r--system/a2tools/a2tools.SlackBuild10
-rw-r--r--system/agedu/agedu.SlackBuild3
-rw-r--r--system/aha/README4
-rw-r--r--system/aha/aha.SlackBuild3
-rw-r--r--system/alacritty/alacritty.SlackBuild4
-rw-r--r--system/alacritty/alacritty.info150
-rw-r--r--system/apg/apg.SlackBuild3
-rw-r--r--system/arc/arc.SlackBuild10
-rw-r--r--system/archivemount/archivemount.SlackBuild3
-rw-r--r--system/arj/README4
-rw-r--r--system/arj/arj.SlackBuild10
-rw-r--r--system/arj/arj.info2
-rw-r--r--system/audit/audit.info4
-rw-r--r--system/augeas/augeas.SlackBuild2
-rw-r--r--system/autocutsel/autocutsel.SlackBuild16
-rw-r--r--system/autocutsel/autocutsel.info8
-rw-r--r--system/bat/bat.SlackBuild45
-rw-r--r--system/bat/bat.info74
-rw-r--r--system/bitmapfont2ttf/README2
-rw-r--r--system/bitmapfont2ttf/bitmapfont2ttf.SlackBuild3
-rw-r--r--system/bitmapfont2ttf/bitmapfont2ttf.info2
-rw-r--r--system/cbmbasic/README5
-rw-r--r--system/cbmbasic/cbmbasic.SlackBuild14
-rw-r--r--system/cbmbasic/cbmbasic.info2
-rw-r--r--system/ccd2cue/ccd2cue.SlackBuild3
-rw-r--r--system/ccd2cue/ccd2cue.info2
-rw-r--r--system/ciopfs/ciopfs.SlackBuild3
-rw-r--r--system/ciopfs/ciopfs.info4
-rw-r--r--system/clamav/clamav.SlackBuild73
-rw-r--r--system/clamav/clamav.info6
-rw-r--r--system/cnijfilter2/cnijfilter2.SlackBuild93
-rw-r--r--system/cnijfilter2/cnijfilter2.info8
-rw-r--r--system/cnijfilter2/gcc10.patch11
-rw-r--r--system/cnijfilter2/slack-desc2
-rw-r--r--system/colorize/colorize.SlackBuild3
-rw-r--r--system/conspy/conspy.SlackBuild3
-rw-r--r--system/cpmtools/cpmtools.SlackBuild3
-rw-r--r--system/crc32_simple/crc32_simple.SlackBuild3
-rw-r--r--system/csh/README9
-rw-r--r--system/csh/csh.SlackBuild40
-rw-r--r--system/csh/csh.info8
-rw-r--r--system/csh/glibc-2.32-sys_siglist.diff38
-rw-r--r--system/d52/d52.SlackBuild10
-rw-r--r--system/d52/d52.info4
-rw-r--r--system/dahdi-complete/dahdi-complete.SlackBuild6
-rw-r--r--system/dahdi-complete/dahdi-complete.info6
-rw-r--r--system/dahdi-complete/patches/01-no-depmod.patch12
-rw-r--r--system/dahdi-complete/patches/02-parallel-make.patch34
-rw-r--r--system/dahdi-complete/patches/04-dahdi-3.1.0-kernel-5.4-support.patch15
-rw-r--r--system/dahdi-complete/patches/05-dahdi-3.1.0-r1-div_s64-for-32-bit-arches.patch11
-rw-r--r--system/dahdi-complete/patches/06-non-digium-hardware-and-oslec.patch18351
-rw-r--r--system/dahdi-complete/patches/07-dahdi-3.1.0-r1-kernel5.6.patch392
-rw-r--r--system/dahdi-complete/patches/08-digium-restore-old-hardwareids.patch29
-rw-r--r--system/dahdi-complete/patches/09-dahdi-3.1.0-r3-remove-32bit-userspace-on-64bit-support.patch94
-rw-r--r--system/dahdi-complete/patches/10-dahdi-3.1.0-r3-ioctl-kernel-5.9.patch155
-rw-r--r--system/dahdi-complete/patches/11-dahdi-3.1.0-r3-clang.patch115
-rw-r--r--system/ded/README10
-rw-r--r--system/ded/ded.SlackBuild3
-rw-r--r--system/ded/ded.info4
-rw-r--r--system/dfu-util/dfu-util.SlackBuild2
-rw-r--r--system/dfu-util/dfu-util.info6
-rw-r--r--system/dina-font/README21
-rw-r--r--system/dina-font/dina-font.SlackBuild10
-rw-r--r--system/dislocker/dislocker.SlackBuild2
-rw-r--r--system/dislocker/ruby3.patch170
-rw-r--r--system/dos33fsprogs/dos33fsprogs.SlackBuild10
-rw-r--r--system/dse-typewriter-font/dse-typewriter-font.SlackBuild3
-rw-r--r--system/edid-decode/edid-decode.SlackBuild5
-rw-r--r--system/edid-decode/edid-decode.info6
-rw-r--r--system/encfs/encfs-openssl-1.1.patch350
-rw-r--r--system/encfs/encfs.SlackBuild27
-rw-r--r--system/encfs/encfs.info6
-rw-r--r--system/esekeyd/esekeyd.SlackBuild3
-rw-r--r--system/etsh/etsh.SlackBuild3
-rw-r--r--system/exomizer/exomizer.SlackBuild7
-rw-r--r--system/exomizer/exomizer.info6
-rw-r--r--system/fbterm/README18
-rw-r--r--system/fbterm/checkfb.185
-rw-r--r--system/fbterm/checkfb.rst73
-rw-r--r--system/fbterm/fbterm.SlackBuild16
-rw-r--r--system/fdclone/fdclone.SlackBuild31
-rw-r--r--system/fdclone/fdclone.info4
-rw-r--r--system/franny/franny.SlackBuild18
-rw-r--r--system/fsarchiver/fsarchiver.SlackBuild2
-rw-r--r--system/fsarchiver/fsarchiver.info6
-rw-r--r--system/fsv/fsv.SlackBuild10
-rw-r--r--system/fsviewer/fsviewer.SlackBuild22
-rw-r--r--system/fsviewer/fsviewer.info2
-rw-r--r--system/fsviewer/get-wraster-flags33
-rw-r--r--system/fwupd/fwupd.SlackBuild3
-rw-r--r--system/fzf/fzf.SlackBuild2
-rw-r--r--system/fzf/fzf.info6
-rw-r--r--system/gammu/gammu.SlackBuild24
-rw-r--r--system/gammu/gammu.info6
-rw-r--r--system/geoclue2/geoclue2.SlackBuild2
-rw-r--r--system/gitolite/gitolite.SlackBuild4
-rw-r--r--system/gitolite/gitolite.info6
-rw-r--r--system/gnu-unifont/gnu-unifont.SlackBuild4
-rw-r--r--system/gnu-unifont/gnu-unifont.info6
-rw-r--r--system/gohu-font/gohu-font.SlackBuild10
-rw-r--r--system/gohu-font/gohu-font.info2
-rw-r--r--system/gphotofs/README8
-rw-r--r--system/gphotofs/gphotofs.SlackBuild10
-rw-r--r--system/heirloom-doctools/heirloom-doctools.SlackBuild22
-rw-r--r--system/heirloom-doctools/heirloom-doctools.info8
-rw-r--r--system/heirloom-doctools/patches/mk.config.patch-191015 (renamed from system/heirloom-doctools/patches/mk.config.patch-160308)0
-rw-r--r--system/hexec/hexec.SlackBuild6
-rw-r--r--system/hexec/hexec.info2
-rw-r--r--system/hungrycat/README10
-rw-r--r--system/hungrycat/hungrycat.SlackBuild10
-rw-r--r--system/hungrycat/hungrycat.info2
-rw-r--r--system/icingaweb2/icingaweb2.SlackBuild5
-rw-r--r--system/info2man/info2man.SlackBuild7
-rw-r--r--system/info2man/info2man.info4
-rw-r--r--system/isextract/isextract.SlackBuild3
-rw-r--r--system/isomd5sum/isomd5sum.SlackBuild10
-rw-r--r--system/jenkins/jenkins.SlackBuild2
-rw-r--r--system/jenkins/jenkins.info8
-rw-r--r--system/joyce/compilefix.diff12
-rw-r--r--system/joyce/joyce.SlackBuild7
-rw-r--r--system/joyce/joyce.info8
-rw-r--r--system/kapacitor/kapacitor.SlackBuild2
-rw-r--r--system/kapacitor/kapacitor.info10
-rw-r--r--system/kegs/kegs.SlackBuild19
-rw-r--r--system/kegs/kegs.info6
-rw-r--r--system/kegs/man/partls.123
-rw-r--r--system/kegs/man/to_pro.155
-rw-r--r--system/kegs/man/xkegs.18
-rw-r--r--system/kfc/kfc.SlackBuild5
-rw-r--r--system/kfc/kfc.info6
-rw-r--r--system/kitty/kitty.SlackBuild36
-rw-r--r--system/kitty/kitty.info6
-rw-r--r--system/kmscon/git2tarxz.sh71
-rw-r--r--system/kmscon/kmscon.SlackBuild24
-rw-r--r--system/kmscon/kmscon.info8
-rw-r--r--system/kmscon/sysmacros.diff22
-rw-r--r--system/lddsafe/lddsafe.SlackBuild3
-rw-r--r--system/letsencrypt/letsencrypt.SlackBuild2
-rw-r--r--system/letsencrypt/letsencrypt.info8
-rw-r--r--system/linux-vt-setcolors/linux-vt-setcolors.SlackBuild5
-rw-r--r--system/linuxconsoletools/README25
-rw-r--r--system/linuxconsoletools/linuxconsoletools.SlackBuild3
-rw-r--r--system/locust/locust.info2
-rw-r--r--system/logwatch/logwatch.SlackBuild4
-rw-r--r--system/logwatch/logwatch.info6
-rw-r--r--system/lv/lv.SlackBuild24
-rw-r--r--system/lv/lv.info8
-rw-r--r--system/lv/patches/change-maximum-height-to-144.patch17
-rw-r--r--system/lv/patches/fix_implicit_decls.diff41
-rw-r--r--system/lv/patches/makefile.diff53
-rw-r--r--system/lv/patches/man_typos.diff65
-rw-r--r--system/lv/patches/no_inline.diff19
-rw-r--r--system/lv/patches/series6
-rw-r--r--system/lv/patches/shows-the-filename-only.diff25
-rw-r--r--system/lynis/lynis.SlackBuild4
-rw-r--r--system/lzop/lzop.SlackBuild3
-rw-r--r--system/lzop/lzop.info4
-rw-r--r--system/macemu/macemu.SlackBuild2
-rw-r--r--system/macutils/README2
-rw-r--r--system/macutils/macutils.SlackBuild10
-rw-r--r--system/macutils/macutils.info6
-rw-r--r--system/makefile2graph/makefile2graph.SlackBuild9
-rw-r--r--system/makepasswd/makepasswd.SlackBuild10
-rw-r--r--system/makepp/makepp.SlackBuild30
-rw-r--r--system/makepp/makepp.info6
-rw-r--r--system/man-pages-es/README4
-rw-r--r--system/man-pages-es/man-pages-es.SlackBuild11
-rw-r--r--system/man-pages-es/man-pages-es.info6
-rw-r--r--system/man-pages-fr/README10
-rw-r--r--system/man-pages-fr/man-pages-fr.SlackBuild22
-rw-r--r--system/man-pages-ja/man-pages-ja.SlackBuild5
-rw-r--r--system/man-pages-ja/man-pages-ja.info6
-rw-r--r--system/man-pages-ru/man-pages-ru.SlackBuild13
-rw-r--r--system/memtester/README8
-rw-r--r--system/memtester/memtester.SlackBuild5
-rw-r--r--system/memtester/memtester.info10
-rw-r--r--system/mmv/mmv.SlackBuild3
-rw-r--r--system/mmv/mmv.info4
-rw-r--r--system/monit/monit.SlackBuild4
-rw-r--r--system/monitoring-plugins/monitoring-plugins.SlackBuild4
-rw-r--r--system/monitoring-plugins/monitoring-plugins.info6
-rw-r--r--system/nilfs-utils/nilfs-utils.SlackBuild32
-rw-r--r--system/nilfs-utils/nilfs-utils.info6
-rw-r--r--system/nut/nut.SlackBuild4
-rw-r--r--system/nvidia-driver/nvidia-driver.SlackBuild44
-rw-r--r--system/nvidia-driver/nvidia-driver.info26
-rw-r--r--system/nvidia-driver/nvidia-installer-removed-sysctl-h.patch36
-rw-r--r--system/nvidia-driver/rc.nvidia-persistenced2
-rw-r--r--system/nvidia-driver/slack-desc2
-rw-r--r--system/nvidia-kernel/nvidia-kernel.SlackBuild6
-rw-r--r--system/nvidia-kernel/nvidia-kernel.info6
-rw-r--r--system/nvidia-legacy390-driver/douninst.sh4
-rw-r--r--system/nvidia-legacy390-driver/nvidia-installer-removed-sysctl-h.patch72
-rw-r--r--system/nvidia-legacy390-driver/nvidia-legacy390-driver.SlackBuild53
-rw-r--r--system/nvidia-legacy390-driver/nvidia-legacy390-driver.info50
-rw-r--r--system/nvidia-legacy390-driver/nvidia-switch11
-rw-r--r--system/nvidia-legacy390-driver/rc.nvidia-persistenced2
-rw-r--r--system/nvidia-legacy390-kernel/README4
-rw-r--r--system/nvidia-legacy390-kernel/kernel-5.12.patch47
-rw-r--r--system/nvidia-legacy390-kernel/kernel-5.13.patch103
-rw-r--r--system/nvidia-legacy390-kernel/kernel-5.14-uvm.patch30
-rw-r--r--system/nvidia-legacy390-kernel/kernel-5.14.patch70
-rw-r--r--system/nvidia-legacy390-kernel/nvidia-legacy390-kernel.SlackBuild12
-rw-r--r--system/nvidia-legacy390-kernel/nvidia-legacy390-kernel.info10
-rw-r--r--system/oldschool-pc-fonts/oldschool-pc-fonts.SlackBuild3
-rw-r--r--system/opendoas/opendoas.SlackBuild7
-rw-r--r--system/openstego/openstego.SlackBuild3
-rw-r--r--system/osquery-bin/osquery-bin.SlackBuild3
-rw-r--r--system/osquery-bin/osquery-bin.info6
-rw-r--r--system/ostree/ostree.SlackBuild2
-rw-r--r--system/ostree/ostree.info6
-rw-r--r--system/otf2bdf/README13
-rw-r--r--system/otf2bdf/otf2bdf.SlackBuild10
-rw-r--r--system/otf2bdf/otf2bdf.info2
-rw-r--r--system/p7zip/p7zip.SlackBuild4
-rw-r--r--system/partimage/compilefix.diff50
-rw-r--r--system/partimage/partimage.SlackBuild17
-rw-r--r--system/partimage/partimage.info4
-rw-r--r--system/pcf2bdf/README6
-rw-r--r--system/pcf2bdf/pcf2bdf.SlackBuild3
-rw-r--r--system/phoronix-test-suite/phoronix-test-suite.SlackBuild2
-rw-r--r--system/phoronix-test-suite/phoronix-test-suite.info6
-rw-r--r--system/pipemeter/README5
-rw-r--r--system/pipemeter/pipemeter.SlackBuild21
-rw-r--r--system/pipemeter/pipemeter.info8
-rw-r--r--system/pipemeter/slack-desc4
-rw-r--r--system/polyglotman/polyglotman.SlackBuild10
-rw-r--r--system/prometheus/prometheus.SlackBuild2
-rw-r--r--system/prometheus/prometheus.info6
-rw-r--r--system/pucrunch/README4
-rw-r--r--system/pucrunch/pucrunch.SlackBuild10
-rw-r--r--system/pv/pv.SlackBuild2
-rw-r--r--system/pv/pv.info6
-rw-r--r--system/pytrash/pytrash.SlackBuild6
-rw-r--r--system/qemu/qemu.info2
-rw-r--r--system/qjoypad/README2
-rw-r--r--system/qjoypad/qjoypad.SlackBuild13
-rw-r--r--system/qjoypad/qjoypad.info6
-rw-r--r--system/qjoypad/slack-desc14
-rw-r--r--system/read-edid/gcc10fix.diff24
-rw-r--r--system/read-edid/read-edid.SlackBuild10
-rw-r--r--system/reptyr/reptyr.SlackBuild3
-rw-r--r--system/restic/restic.SlackBuild2
-rw-r--r--system/restic/restic.info10
-rw-r--r--system/rtirq/README2
-rw-r--r--system/rtirq/git2tarxz.sh44
-rw-r--r--system/rtirq/rtirq.SlackBuild25
-rw-r--r--system/rtirq/rtirq.info8
-rw-r--r--system/rtirq/slack-desc2
-rw-r--r--system/s3fs-fuse/s3fs-fuse.SlackBuild2
-rw-r--r--system/s3fs-fuse/s3fs-fuse.info6
-rw-r--r--system/salt/salt.info2
-rw-r--r--system/sandy/README10
-rw-r--r--system/sandy/sandy.SlackBuild10
-rw-r--r--system/scangearmp2/doinst.sh5
-rw-r--r--system/scangearmp2/scangearmp2.SlackBuild33
-rw-r--r--system/scangearmp2/scangearmp2.info8
-rw-r--r--system/scangearmp2/slack-desc2
-rw-r--r--system/sdl-jstest/README4
-rw-r--r--system/sdl-jstest/sdl-jstest.SlackBuild3
-rw-r--r--system/skim/skim.SlackBuild4
-rw-r--r--system/sleuthkit/sleuthkit.SlackBuild4
-rw-r--r--system/sleuthkit/sleuthkit.info6
-rw-r--r--system/slim/CMakeLists.txt.patch14
-rw-r--r--system/slim/README2
-rw-r--r--system/slim/files/Xsession158
-rw-r--r--system/slim/files/slim.logrotate (renamed from system/slim/slim.logrotate)0
-rw-r--r--system/slim/files/slim.pam7
-rw-r--r--system/slim/files/slimlock.pam3
-rw-r--r--system/slim/patches/slim-1.3.6-config.diff60
-rw-r--r--system/slim/patches/slim-1.3.6-envcpy-bad-pointer-arithmetic.patch15
-rw-r--r--system/slim/patches/slim-1.3.6-gcc11.patch12
-rw-r--r--system/slim/patches/slim-1.3.6-honour-cflags.patch14
-rw-r--r--system/slim/patches/slim-1.3.6-libslim-cmake-fixes.patch33
-rw-r--r--system/slim/patches/slim-1.3.6-session-chooser.patch115
-rw-r--r--system/slim/patches/slim-1.3.6_freetype-2.5.1.diff (renamed from system/slim/slim-1.3.6_freetype-2.5.1.diff)0
-rw-r--r--system/slim/slim.SlackBuild37
-rw-r--r--system/slim/slim.conf.patch11
-rw-r--r--system/snapscreenshot/snapscreenshot.SlackBuild14
-rw-r--r--system/snapscreenshot/snapscreenshot.info6
-rw-r--r--system/solarize-12x29-psf/solarize-12x29-psf.SlackBuild4
-rw-r--r--system/spice-vdagent/files/rc.spice-vdagent1
-rw-r--r--system/spman/spman.SlackBuild8
-rw-r--r--system/statifier/statifier.SlackBuild10
-rw-r--r--system/statifier/statifier.info2
-rw-r--r--system/suckless-tools/README10
-rw-r--r--system/suckless-tools/suckless-tools.SlackBuild13
-rw-r--r--system/tabbed/tabbed.SlackBuild10
-rw-r--r--system/telegraf/telegraf.SlackBuild2
-rw-r--r--system/telegraf/telegraf.info10
-rw-r--r--system/tinyterm/README14
-rw-r--r--system/tinyterm/slack-desc6
-rw-r--r--system/tinyterm/tinyterm.SlackBuild23
-rw-r--r--system/trackfs/trackfs.SlackBuild10
-rw-r--r--system/triggerhappy/README20
-rw-r--r--system/triggerhappy/rc.triggerhappy6
-rw-r--r--system/triggerhappy/slack-desc2
-rw-r--r--system/triggerhappy/triggerhappy.SlackBuild5
-rw-r--r--system/ttf-ancient-fonts/ttf-ancient-fonts.SlackBuild3
-rw-r--r--system/ttf-ancient-fonts/ttf-ancient-fonts.info2
-rw-r--r--system/ttf-console-fonts/ttf-console-fonts.SlackBuild10
-rw-r--r--system/u3-tool/README16
-rw-r--r--system/u3-tool/slack-desc10
-rw-r--r--system/u3-tool/u3-tool.SlackBuild27
-rw-r--r--system/u3-tool/u3-tool.info8
-rw-r--r--system/uhd/uhd.info2
-rw-r--r--system/unac/README12
-rw-r--r--system/unac/ligatures.diff (renamed from system/unac/oe_ligature.diff)9
-rw-r--r--system/unac/size_t.diff45
-rw-r--r--system/unac/slack-desc10
-rw-r--r--system/unac/unac.SlackBuild46
-rw-r--r--system/unac/unac.info10
-rw-r--r--system/unetbootin/unetbootin.SlackBuild8
-rw-r--r--system/unicode-character-database/unicode-character-database.SlackBuild4
-rw-r--r--system/unicode-character-database/unicode-character-database.info10
-rw-r--r--system/unigine-heaven-benchmark/unigine-heaven-benchmark.SlackBuild6
-rw-r--r--system/unigine-heaven-benchmark/unigine-heaven-benchmark.desktop2
-rw-r--r--system/unigine-valley-benchmark/unigine-valley-benchmark.SlackBuild6
-rw-r--r--system/unigine-valley-benchmark/unigine-valley-benchmark.desktop2
-rw-r--r--system/univga-font/univga-font.SlackBuild3
-rw-r--r--system/univga-font/univga-font.info4
-rw-r--r--system/unshield/README11
-rw-r--r--system/unshield/slack-desc4
-rw-r--r--system/unshield/unshield.SlackBuild55
-rw-r--r--system/unshield/unshield.info8
-rw-r--r--system/usbmon/usbmon.SlackBuild10
-rw-r--r--system/usbredir/usbredir.SlackBuild2
-rw-r--r--system/usermin/usermin.SlackBuild2
-rw-r--r--system/usermin/usermin.info6
-rw-r--r--system/v4l2loopback/v4l2loopback.SlackBuild2
-rw-r--r--system/v4l2loopback/v4l2loopback.info2
-rw-r--r--system/vcp/vcp.SlackBuild12
-rw-r--r--system/vice/README11
-rw-r--r--system/vice/README_SBo.txt21
-rw-r--r--system/vice/config/vice.pngbin4040 -> 0 bytes
-rw-r--r--system/vice/config/vsid.desktop9
-rw-r--r--system/vice/config/x128.desktop9
-rw-r--r--system/vice/config/x64.desktop9
-rw-r--r--system/vice/config/x64dtv.desktop9
-rw-r--r--system/vice/config/x64sc.desktop9
-rw-r--r--system/vice/config/xcbm2.desktop9
-rw-r--r--system/vice/config/xcbm5x0.desktop9
-rw-r--r--system/vice/config/xpet.desktop9
-rw-r--r--system/vice/config/xplus4.desktop9
-rw-r--r--system/vice/config/xscpu64.desktop9
-rw-r--r--system/vice/config/xvic.desktop9
-rw-r--r--system/vice/doinst.sh16
-rw-r--r--system/vice/man/c1541.1162
-rw-r--r--system/vice/man/cartconv.1247
-rw-r--r--system/vice/man/petcat.1219
-rw-r--r--system/vice/man/vice.1183
-rw-r--r--system/vice/man/vsid.124
-rw-r--r--system/vice/slack-desc2
-rw-r--r--system/vice/vice.SlackBuild318
-rw-r--r--system/vice/vice.info8
-rw-r--r--system/vifm/vifm.SlackBuild3
-rw-r--r--system/vinterm/README20
-rw-r--r--system/vinterm/vinterm.SlackBuild10
-rw-r--r--system/virtualbox-addons/LocalConfig.kmk2
-rw-r--r--system/virtualbox-addons/README.SLACKWARE10
-rw-r--r--system/virtualbox-addons/kded5rc2
-rw-r--r--system/virtualbox-addons/kwin_blacklist_vbox.sh8
-rw-r--r--system/virtualbox-addons/kwinrc2
-rw-r--r--system/virtualbox-addons/plasma_disable_kscreen.sh3
-rw-r--r--system/virtualbox-addons/rc.vboxadd.diff280
-rw-r--r--system/virtualbox-addons/vbox-uninstall-guest-additions2
-rw-r--r--system/virtualbox-addons/virtualbox-addons.SlackBuild83
-rw-r--r--system/virtualbox-addons/virtualbox-addons.info6
-rw-r--r--system/virtualbox-addons/virtualbox_plasma_disable_kscreen.upd6
-rw-r--r--system/virtualbox-extension-pack/virtualbox-extension-pack.SlackBuild2
-rw-r--r--system/virtualbox-extension-pack/virtualbox-extension-pack.info6
-rw-r--r--system/virtualbox-kernel-addons/COPYING365
-rw-r--r--system/virtualbox-kernel-addons/COPYING.CDDL381
-rw-r--r--system/virtualbox-kernel-addons/README14
-rw-r--r--system/virtualbox-kernel-addons/doinst.sh1
-rw-r--r--system/virtualbox-kernel-addons/slack-desc19
-rw-r--r--system/virtualbox-kernel-addons/virtualbox-kernel-addons-mksrctarball.sh27
-rw-r--r--system/virtualbox-kernel-addons/virtualbox-kernel-addons.SlackBuild124
-rw-r--r--system/virtualbox-kernel-addons/virtualbox-kernel-addons.info10
-rw-r--r--system/virtualbox-kernel/README3
-rw-r--r--system/virtualbox-kernel/virtualbox-kernel.SlackBuild27
-rw-r--r--system/virtualbox-kernel/virtualbox-kernel.info6
-rw-r--r--system/virtualbox/README7
-rw-r--r--system/virtualbox/vboxdrv.sh-setup.diff37
-rw-r--r--system/virtualbox/virtualbox.SlackBuild66
-rw-r--r--system/virtualbox/virtualbox.info18
-rw-r--r--system/vlock/README19
-rw-r--r--system/vlock/vlock.SlackBuild10
-rw-r--r--system/volatility/volatility.info2
-rw-r--r--system/wdiff/wdiff.SlackBuild19
-rw-r--r--system/wdiff/wdiff.info2
-rw-r--r--system/webmin/webmin.SlackBuild2
-rw-r--r--system/webmin/webmin.info6
-rw-r--r--system/wine-staging/wine-staging.SlackBuild4
-rw-r--r--system/wine-staging/wine-staging.info10
-rw-r--r--system/wine/wine.SlackBuild2
-rw-r--r--system/wine/wine.info6
-rw-r--r--system/wmgtemp/fixes.diff192
-rw-r--r--system/wmgtemp/wmgtemp.SlackBuild14
-rw-r--r--system/worker/worker.SlackBuild2
-rw-r--r--system/worker/worker.info6
-rw-r--r--system/xarchiver/xarchiver.info2
-rw-r--r--system/xautomation/030_xmousepos-add-xautomation-manpage.patch33
-rw-r--r--system/xautomation/README11
-rw-r--r--system/xautomation/slack-desc2
-rw-r--r--system/xautomation/xautomation.SlackBuild39
-rw-r--r--system/xautomation/xautomation.info4
-rw-r--r--system/xen/README1
-rw-r--r--system/xen/dom0/README.dom0118
-rw-r--r--system/xen/dom0/config-4.4.240-xen.i6867450
-rw-r--r--system/xen/dom0/config-5.14.12-xen.x86_64 (renamed from system/xen/dom0/config-4.4.240-xen.x86_64)6319
-rw-r--r--system/xen/dom0/kernel-xen.sh22
-rw-r--r--system/xen/domU/domU.sh2
-rw-r--r--system/xen/domU/mydom6
-rw-r--r--system/xen/patches/0001-BaseTools-fix-ucs-2-lookup-on-python-3.9.patch49
-rw-r--r--system/xen/patches/0002-BaseTools-Work-around-array.array.tostring-removal-i.patch51
-rw-r--r--system/xen/patches/0003-BaseTools-replace-deprecated-fromstring-and-tostring.diff60
-rw-r--r--system/xen/patches/edk2-ovmf-202105-werror.patch38
-rw-r--r--system/xen/patches/qemu-xen-no-pie.diff26
-rw-r--r--system/xen/patches/symlinks_instead_of_hardlinks.diff20
-rw-r--r--system/xen/patches/tools-ipxe-update-for-fixing-build-with-GCC11.diff13
-rw-r--r--system/xen/xen.SlackBuild46
-rw-r--r--system/xen/xen.info18
-rw-r--r--system/xen/xsa/xsa317.patch50
-rw-r--r--system/xen/xsa/xsa319.patch27
-rw-r--r--system/xen/xsa/xsa320-4.13-1.patch117
-rw-r--r--system/xen/xsa/xsa320-4.13-2.patch179
-rw-r--r--system/xen/xsa/xsa320-4.13-3.patch36
-rw-r--r--system/xen/xsa/xsa327.patch63
-rw-r--r--system/xen/xsa/xsa328-4.13-1.patch118
-rw-r--r--system/xen/xsa/xsa328-4.13-2.patch48
-rw-r--r--system/xen/xsa/xsa328-post-xsa321-4.13-1.patch31
-rw-r--r--system/xen/xsa/xsa328-post-xsa321-4.13-2.patch175
-rw-r--r--system/xen/xsa/xsa328-post-xsa321-4.13-3.patch82
-rw-r--r--system/xen/xsa/xsa328-post-xsa321-4.13-4.patch36
-rw-r--r--system/xen/xsa/xsa328-post-xsa321-4.13-5.patch24
-rw-r--r--system/xen/xsa/xsa328-post-xsa321-4.13-6.patch91
-rw-r--r--system/xen/xsa/xsa328-post-xsa321-4.13-7.patch153
-rw-r--r--system/xen/xsa/xsa333.patch39
-rw-r--r--system/xen/xsa/xsa334.patch51
-rw-r--r--system/xen/xsa/xsa335-qemu.patch84
-rw-r--r--system/xen/xsa/xsa336.patch283
-rw-r--r--system/xen/xsa/xsa337-4.13-1.patch87
-rw-r--r--system/xen/xsa/xsa337-4.13-2.patch181
-rw-r--r--system/xen/xsa/xsa338.patch42
-rw-r--r--system/xen/xsa/xsa339.patch76
-rw-r--r--system/xen/xsa/xsa340.patch65
-rw-r--r--system/xen/xsa/xsa342-4.13.patch145
-rw-r--r--system/xen/xsa/xsa343-1.patch199
-rw-r--r--system/xen/xsa/xsa343-2.patch295
-rw-r--r--system/xen/xsa/xsa343-3.patch392
-rw-r--r--system/xen/xsa/xsa344-4.13-1.patch130
-rw-r--r--system/xen/xsa/xsa344-4.13-2.patch203
-rw-r--r--system/xen/xsa/xsa345-0001-x86-mm-Refactor-map_pages_to_xen-to-have-only-a-sing.patch94
-rw-r--r--system/xen/xsa/xsa345-0002-x86-mm-Refactor-modify_xen_mappings-to-have-one-exit.patch68
-rw-r--r--system/xen/xsa/xsa345-0003-x86-mm-Prevent-some-races-in-hypervisor-mapping-upda.patch249
-rw-r--r--system/xen/xsa/xsa346-4.13-1.patch50
-rw-r--r--system/xen/xsa/xsa346-4.13-2.patch204
-rw-r--r--system/xen/xsa/xsa347-4.13-1.patch149
-rw-r--r--system/xen/xsa/xsa347-4.13-2.patch72
-rw-r--r--system/xen/xsa/xsa347-4.13-3.patch59
-rw-r--r--system/xen/xsa/xsa386.patch29
-rw-r--r--system/xidel/xidel.SlackBuild3
-rw-r--r--system/yeahconsole/52-yeahkeys.patch21
-rw-r--r--system/yeahconsole/yeahconsole.124
-rw-r--r--system/yeahconsole/yeahconsole.SlackBuild20
-rw-r--r--system/yeahconsole/yeahconsole.xml19
476 files changed, 28280 insertions, 17927 deletions
diff --git a/system/AnonymousPro/AnonymousPro.SlackBuild b/system/AnonymousPro/AnonymousPro.SlackBuild
index 5f61b11278..6aa27a688f 100644
--- a/system/AnonymousPro/AnonymousPro.SlackBuild
+++ b/system/AnonymousPro/AnonymousPro.SlackBuild
@@ -2,7 +2,7 @@
# Slackware build script for AnonymousPro
-# Copyright 2014-2015 Eugene M., <damagedone at gmx dot com>
+# Copyright 2014-2021 Eugene M., <damagedone at gmx dot com>
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@@ -25,8 +25,9 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=AnonymousPro
-VERSION=${VERSION:-1.002}
-BUILD=${BUILD:-2}
+VERSION=${VERSION:-1_002}
+DIR_NAME=${DIR_NAME:-1.002.001}
+BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
@@ -51,14 +52,9 @@ mkdir -p $TMP $PKG $OUTPUT
cd $TMP
rm -rf $PRGNAM-$VERSION
unzip $CWD/$PRGNAM-$VERSION.zip
-unzip $CWD/AnonymousProMinus-1.003.zip
-# Ugly hack
-mv -f $PRGNAM-$VERSION.001 $PRGNAM-$VERSION
+mv -f $PRGNAM-$DIR_NAME $PRGNAM-$VERSION
mv $PRGNAM-$VERSION/FONTLOG.txt $PRGNAM-$VERSION/AnonymousPro_FONTLOG.txt
-mv -f AnonymousProMinus-1.003/*.* $PRGNAM-$VERSION
-mv $PRGNAM-$VERSION/FONTLOG.txt $PRGNAM-$VERSION/AnonymousProMinus_FONTLOG.txt
-rm -rf ._AnonymousPro-1.002.001 AnonymousProMinus-1.003
cd $PRGNAM-$VERSION
chown -R root:root .
find -L . \
diff --git a/system/AnonymousPro/AnonymousPro.info b/system/AnonymousPro/AnonymousPro.info
index ca0b989459..a40ba80c58 100644
--- a/system/AnonymousPro/AnonymousPro.info
+++ b/system/AnonymousPro/AnonymousPro.info
@@ -1,10 +1,8 @@
PRGNAM="AnonymousPro"
-VERSION="1.002"
+VERSION="1_002"
HOMEPAGE="https://www.marksimonson.com/fonts/view/anonymous-pro"
-DOWNLOAD="https://www.marksimonson.com/assets/content/fonts/AnonymousPro-1.002.zip \
- https://www.marksimonson.com/assets/content/fonts/AnonymousProMinus-1.003.zip"
-MD5SUM="bb5141b20b9d69b3190be03e5706c8b7 \
- 16468f49e2a56f8e2ad39f09728391bd"
+DOWNLOAD="https://www.marksimonson.com/assets/content/fonts/AnonymousPro-1_002.zip"
+MD5SUM="aac53fb8fdb238e84072a94f5721bbec"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
diff --git a/system/AnonymousPro/doinst.sh b/system/AnonymousPro/doinst.sh
index 883c47ac0a..f0ffee7710 100644
--- a/system/AnonymousPro/doinst.sh
+++ b/system/AnonymousPro/doinst.sh
@@ -1,10 +1,10 @@
# Update the X font indexes:
+
if [ -x /usr/bin/mkfontdir ]; then
- ( cd /usr/share/fonts/TTF
- mkfontscale .
- mkfontdir .
+ ( cd usr/share/fonts/TTF
+ /usr/bin/mkfontscale .
+ /usr/bin/mkfontdir .
)
-fi
-if [ -x /usr/bin/fc-cache ]; then
- /usr/bin/fc-cache -f
+
+ [ -x /usr/bin/fc-cache ] && /usr/bin/fc-cache -f
fi
diff --git a/system/Iosevka-slab/Iosevka-slab.SlackBuild b/system/Iosevka-slab/Iosevka-slab.SlackBuild
index 10052dc3b0..715370a758 100644
--- a/system/Iosevka-slab/Iosevka-slab.SlackBuild
+++ b/system/Iosevka-slab/Iosevka-slab.SlackBuild
@@ -25,7 +25,7 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=Iosevka-slab
-VERSION=${VERSION:-5.1.1}
+VERSION=${VERSION:-10.3.0}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
diff --git a/system/Iosevka-slab/Iosevka-slab.info b/system/Iosevka-slab/Iosevka-slab.info
index 1d011a5459..4fd9e163fe 100644
--- a/system/Iosevka-slab/Iosevka-slab.info
+++ b/system/Iosevka-slab/Iosevka-slab.info
@@ -1,8 +1,8 @@
PRGNAM="Iosevka-slab"
-VERSION="5.1.1"
+VERSION="10.3.0"
HOMEPAGE="https://typeof.net/Iosevka/"
-DOWNLOAD="https://github.com/be5invis/Iosevka/releases/download/v5.1.1/ttc-iosevka-slab-5.1.1.zip"
-MD5SUM="e0d5b48c59fc117a6fbbf7ee1b821461"
+DOWNLOAD="https://github.com/be5invis/Iosevka/releases/download/v10.3.0/ttc-iosevka-slab-10.3.0.zip"
+MD5SUM="d2c2430fcd9d98a98c017d65f70cfd50"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
diff --git a/system/Iosevka/Iosevka.SlackBuild b/system/Iosevka/Iosevka.SlackBuild
index 91e3223179..41f46bca1d 100644
--- a/system/Iosevka/Iosevka.SlackBuild
+++ b/system/Iosevka/Iosevka.SlackBuild
@@ -25,7 +25,7 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=Iosevka
-VERSION=${VERSION:-5.1.1}
+VERSION=${VERSION:-10.3.0}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
diff --git a/system/Iosevka/Iosevka.info b/system/Iosevka/Iosevka.info
index 13e3da213a..b4051aa3a3 100644
--- a/system/Iosevka/Iosevka.info
+++ b/system/Iosevka/Iosevka.info
@@ -1,8 +1,8 @@
PRGNAM="Iosevka"
-VERSION="5.1.1"
+VERSION="10.3.0"
HOMEPAGE="https://typeof.net/Iosevka/"
-DOWNLOAD="https://github.com/be5invis/Iosevka/releases/download/v5.1.1/ttc-iosevka-5.1.1.zip"
-MD5SUM="223ff002dcad132138f2b3b0602c5162"
+DOWNLOAD="https://github.com/be5invis/Iosevka/releases/download/v10.3.0/ttc-iosevka-10.3.0.zip"
+MD5SUM="610475984d546274950dc1f30d80ae32"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
diff --git a/system/Sl/Sl.SlackBuild b/system/Sl/Sl.SlackBuild
index 5dfca63d83..3e7726a779 100644
--- a/system/Sl/Sl.SlackBuild
+++ b/system/Sl/Sl.SlackBuild
@@ -18,9 +18,6 @@ TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
ARCH=noarch
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/Sl/Sl.info b/system/Sl/Sl.info
index 37bd254292..9229e34ab8 100644
--- a/system/Sl/Sl.info
+++ b/system/Sl/Sl.info
@@ -1,7 +1,7 @@
PRGNAM="Sl"
VERSION="1.1.3"
-HOMEPAGE="http://web.archive.org/web/20131228142311/http://practicalthought.com/sl/"
-DOWNLOAD="http://web.archive.org/web/20150726011829/http://practicalthought.com:80/sl/sl"
+HOMEPAGE="https://web.archive.org/web/20131228142311/http://practicalthought.com/sl/"
+DOWNLOAD="https://web.archive.org/web/20150726011829/http://practicalthought.com:80/sl/sl"
MD5SUM="ed4c22a531e957c95df5f41206d6ed2f"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
diff --git a/system/a2tools/a2tools.SlackBuild b/system/a2tools/a2tools.SlackBuild
index 6e0aa3abc4..ca5f2119bb 100644
--- a/system/a2tools/a2tools.SlackBuild
+++ b/system/a2tools/a2tools.SlackBuild
@@ -22,9 +22,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
@@ -57,11 +54,8 @@ rm -rf $PRGNAM
unzip $CWD/$PRGNAM-v$VERSION.zip
cd $PRGNAM
chown -R root:root .
-find -L . \
- \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
- -o -perm 511 \) -exec chmod 755 {} \; -o \
- \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
- -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
+find -L . -perm /111 -a \! -perm 755 -a -exec chmod 755 {} \+ -o \
+ \! -perm /111 -a \! -perm 644 -a -exec chmod 644 {} \+
# It doesn't come with a Makefile, it comes with a csh script. Don't
# use it...
diff --git a/system/agedu/agedu.SlackBuild b/system/agedu/agedu.SlackBuild
index 5adc86d82f..3ecbea3f48 100644
--- a/system/agedu/agedu.SlackBuild
+++ b/system/agedu/agedu.SlackBuild
@@ -31,9 +31,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/aha/README b/system/aha/README
index 209bf1359d..555f625c75 100644
--- a/system/aha/README
+++ b/system/aha/README
@@ -1,5 +1,5 @@
aha (convert ANSI color/graphics to HTML)
aha (ANSI HTML Adapter) converts ANSI colors to HTML, e.g. if you want
-to publish the output of ls --color=yes, git diff, ccal or htop as static
-HTML somewhere.
+to publish the output of ls --color=yes, git diff, ccal or htop as
+static HTML somewhere.
diff --git a/system/aha/aha.SlackBuild b/system/aha/aha.SlackBuild
index af1966e6cc..65aba41a15 100644
--- a/system/aha/aha.SlackBuild
+++ b/system/aha/aha.SlackBuild
@@ -29,9 +29,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/alacritty/alacritty.SlackBuild b/system/alacritty/alacritty.SlackBuild
index 8c37f16dd9..f038d7d95c 100644
--- a/system/alacritty/alacritty.SlackBuild
+++ b/system/alacritty/alacritty.SlackBuild
@@ -25,8 +25,8 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=alacritty
-VERSION=${VERSION:-0.8.0}
-BUILD=${BUILD:-2}
+VERSION=${VERSION:-0.9.0}
+BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
diff --git a/system/alacritty/alacritty.info b/system/alacritty/alacritty.info
index 862a9e54a0..6f74566d56 100644
--- a/system/alacritty/alacritty.info
+++ b/system/alacritty/alacritty.info
@@ -1,19 +1,19 @@
PRGNAM="alacritty"
-VERSION="0.8.0"
+VERSION="0.9.0"
HOMEPAGE="https://github.com/jwilm/alacritty"
-DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.gz \
+DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.9.0/alacritty-0.9.0.tar.gz \
https://crates-io.s3-us-west-1.amazonaws.com/crates/ab_glyph_rasterizer/ab_glyph_rasterizer-0.1.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/adler32/adler32-1.2.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/andrew/andrew-0.3.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/android_glue/android_glue-0.2.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/ansi_term/ansi_term-0.11.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/atty/atty-0.2.14.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/autocfg/autocfg-1.0.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/base64/base64-0.13.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/bitflags/bitflags-1.2.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/block/block-0.1.6.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/byteorder/byteorder-1.4.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/calloop/calloop-0.6.5.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/cc/cc-1.0.67.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/cc/cc-1.0.69.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/cfg-if/cfg-if-0.1.10.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/cfg-if/cfg-if-1.0.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/cgl/cgl-0.3.2.crate \
@@ -34,7 +34,7 @@ DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.
https://crates-io.s3-us-west-1.amazonaws.com/crates/core-text/core-text-19.2.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/core-video-sys/core-video-sys-0.1.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/crc32fast/crc32fast-1.2.1.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/crossfont/crossfont-0.3.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/crossfont/crossfont-0.3.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/darling/darling-0.10.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/darling_core/darling_core-0.10.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/darling_macro/darling_macro-0.10.2.crate \
@@ -47,7 +47,7 @@ DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.
https://crates-io.s3-us-west-1.amazonaws.com/crates/downcast-rs/downcast-rs-1.2.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/dtoa/dtoa-0.4.8.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/dwrote/dwrote-0.11.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/embed-resource/embed-resource-1.6.2.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/embed-resource/embed-resource-1.6.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/expat-sys/expat-sys-2.1.6.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/filetime/filetime-0.2.14.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/fnv/fnv-1.0.7.crate \
@@ -62,7 +62,7 @@ DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.
https://crates-io.s3-us-west-1.amazonaws.com/crates/fsevent/fsevent-0.4.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/fuchsia-zircon-sys/fuchsia-zircon-sys-0.3.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/fuchsia-zircon/fuchsia-zircon-0.3.3.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/getrandom/getrandom-0.2.2.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/getrandom/getrandom-0.2.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/gl_generator/gl_generator-0.14.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/glutin/glutin-0.26.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/glutin_egl_sys/glutin_egl_sys-0.1.5.crate \
@@ -70,11 +70,11 @@ DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.
https://crates-io.s3-us-west-1.amazonaws.com/crates/glutin_gles2_sys/glutin_gles2_sys-0.1.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/glutin_glx_sys/glutin_glx_sys-0.1.7.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/glutin_wgl_sys/glutin_wgl_sys-0.1.5.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/hermit-abi/hermit-abi-0.1.18.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/hermit-abi/hermit-abi-0.1.19.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/ident_case/ident_case-1.0.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/inotify-sys/inotify-sys-0.1.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/inotify/inotify-0.7.1.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/instant/instant-0.1.9.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/instant/instant-0.1.10.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/iovec/iovec-0.1.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/itoa/itoa-0.4.7.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/jni-sys/jni-sys-0.3.0.crate \
@@ -83,7 +83,7 @@ DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.
https://crates-io.s3-us-west-1.amazonaws.com/crates/lazy-bytes-cast/lazy-bytes-cast-5.0.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/lazy_static/lazy_static-1.4.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/lazycell/lazycell-1.3.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/libc/libc-0.2.94.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/libc/libc-0.2.98.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/libloading/libloading-0.6.7.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/libloading/libloading-0.7.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/linked-hash-map/linked-hash-map-0.5.4.crate \
@@ -91,10 +91,12 @@ DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.
https://crates-io.s3-us-west-1.amazonaws.com/crates/log/log-0.4.14.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/malloc_buf/malloc_buf-0.0.6.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/maybe-uninit/maybe-uninit-2.0.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/memchr/memchr-2.4.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/memchr/memchr-2.3.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/memmap2/memmap2-0.1.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/memmap2/memmap2-0.2.3.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/memoffset/memoffset-0.6.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/miniz_oxide/miniz_oxide-0.3.7.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/mio-anonymous-pipes/mio-anonymous-pipes-0.1.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/mio-anonymous-pipes/mio-anonymous-pipes-0.2.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/mio-extras/mio-extras-2.0.6.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/mio/mio-0.6.23.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/miow/miow-0.2.2.crate \
@@ -106,14 +108,15 @@ DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.
https://crates-io.s3-us-west-1.amazonaws.com/crates/net2/net2-0.2.37.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/nix/nix-0.18.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/nix/nix-0.20.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/nom/nom-6.1.2.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/notify/notify-4.0.16.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/nix/nix-0.22.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/nom/nom-6.2.1.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/notify/notify-4.0.17.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/num_enum/num_enum-0.4.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/num_enum_derive/num_enum_derive-0.4.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/objc-foundation/objc-foundation-0.1.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/objc/objc-0.2.7.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/objc_id/objc_id-0.1.1.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/once_cell/once_cell-1.7.2.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/once_cell/once_cell-1.8.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/osmesa-sys/osmesa-sys-0.1.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/owned_ttf_parser/owned_ttf_parser-0.6.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/parking_lot/parking_lot-0.11.1.crate \
@@ -122,38 +125,39 @@ DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.
https://crates-io.s3-us-west-1.amazonaws.com/crates/pkg-config/pkg-config-0.3.19.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/png/png-0.16.8.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/proc-macro-crate/proc-macro-crate-0.1.5.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/proc-macro2/proc-macro2-1.0.26.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/proc-macro2/proc-macro2-1.0.28.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/quote/quote-1.0.9.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/raw-window-handle/raw-window-handle-0.3.3.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/redox_syscall/redox_syscall-0.2.8.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/redox_syscall/redox_syscall-0.2.9.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/redox_users/redox_users-0.4.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/regex-automata/regex-automata-0.1.9.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/regex-automata/regex-automata-0.1.10.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/regex-syntax/regex-syntax-0.6.25.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/rusttype/rusttype-0.9.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/ryu/ryu-1.0.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/same-file/same-file-1.0.6.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/scoped-tls/scoped-tls-1.0.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/scopeguard/scopeguard-1.1.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/serde/serde-1.0.125.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/serde_derive/serde_derive-1.0.125.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/serde_json/serde_json-1.0.64.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/serde/serde-1.0.127.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/serde_derive/serde_derive-1.0.127.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/serde_json/serde_json-1.0.66.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/serde_yaml/serde_yaml-0.8.17.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/servo-fontconfig-sys/servo-fontconfig-sys-5.1.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/servo-fontconfig/servo-fontconfig-0.5.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/shared_library/shared_library-0.1.9.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/signal-hook-registry/signal-hook-registry-1.3.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/signal-hook-registry/signal-hook-registry-1.4.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/signal-hook/signal-hook-0.1.17.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/slab/slab-0.4.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/smallvec/smallvec-1.6.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/smithay-client-toolkit/smithay-client-toolkit-0.12.3.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/smithay-clipboard/smithay-clipboard-0.6.3.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/smithay-client-toolkit/smithay-client-toolkit-0.14.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/smithay-clipboard/smithay-clipboard-0.6.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/spsc-buffer/spsc-buffer-0.1.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/strsim/strsim-0.8.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/strsim/strsim-0.9.3.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/syn/syn-1.0.72.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/syn/syn-1.0.74.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/textwrap/textwrap-0.11.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/thiserror-impl/thiserror-impl-1.0.24.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/thiserror/thiserror-1.0.24.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/thiserror-impl/thiserror-impl-1.0.26.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/thiserror/thiserror-1.0.26.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/time/time-0.1.43.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/toml/toml-0.5.8.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/ttf-parser/ttf-parser-0.6.2.crate \
@@ -168,13 +172,13 @@ DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.
https://crates-io.s3-us-west-1.amazonaws.com/crates/vte_generate_state_changes/vte_generate_state_changes-0.1.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/walkdir/walkdir-2.3.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/wasi/wasi-0.10.2+wasi-snapshot-preview1.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-client/wayland-client-0.28.5.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-commons/wayland-commons-0.28.5.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-cursor/wayland-cursor-0.28.5.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-egl/wayland-egl-0.28.5.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-protocols/wayland-protocols-0.28.5.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-scanner/wayland-scanner-0.28.5.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-sys/wayland-sys-0.28.5.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-client/wayland-client-0.28.6.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-commons/wayland-commons-0.28.6.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-cursor/wayland-cursor-0.28.6.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-egl/wayland-egl-0.28.6.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-protocols/wayland-protocols-0.28.6.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-scanner/wayland-scanner-0.28.6.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/wayland-sys/wayland-sys-0.28.6.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/winapi-build/winapi-build-0.1.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/winapi-i686-pc-windows-gnu/winapi-i686-pc-windows-gnu-0.4.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/winapi-util/winapi-util-0.1.5.crate \
@@ -182,29 +186,29 @@ DOWNLOAD="https://github.com/jwilm/alacritty/archive/v0.8.0/alacritty-0.8.0.tar.
https://crates-io.s3-us-west-1.amazonaws.com/crates/winapi/winapi-0.2.8.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/winapi/winapi-0.3.9.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/winit/winit-0.24.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/winreg/winreg-0.8.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/winreg/winreg-0.9.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/wio/wio-0.2.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/ws2_32-sys/ws2_32-sys-0.2.1.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/x11-clipboard/x11-clipboard-0.5.1.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/x11-clipboard/x11-clipboard-0.5.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/x11-dl/x11-dl-2.18.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/xcb/xcb-0.9.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/xcursor/xcursor-0.3.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/xdg/xdg-2.2.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/xml-rs/xml-rs-0.8.3.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/xml-rs/xml-rs-0.8.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/yaml-rust/yaml-rust-0.4.5.crate"
-MD5SUM="47bfc192b29252bab6fb436a1b71458d \
+MD5SUM="393d34a29db21390964181b73cf9cba1 \
b6ff84389c3d3774cffa7aa3edb2457f \
d5898ddb1e496ff0ac50b79829311e76 \
ca8db5ddb6d3ab160f7ecb985a640ce5 \
196a2eb81627baf71f6677a3c669e6ac \
294a49d3c53865fa7ac5d0ce2f5d5735 \
142cb4b9a653e56e56311f0c883b8582 \
+ c6443ec8d007c729ba5482008d0c864d \
80a2c27647a6acb1890a3a7de8fded72 \
6799c26a7eacaf8e58d3e45c6c5add89 \
ea2d23ceb9f98853a7dffc6c02884464 \
- 1e704be5ddde9d6b5383ef1035309f91 \
7f4f37da02b16d6deda378dcea8e5a17 \
- 8637708206e07c0b9e726c7b2f4412d6 \
+ 5ce70859dbf179ad0e89769c83fe00c7 \
882dbbc613a93f64c3709b0a2bd0d6dc \
74634128440dbc3766bda76fdf0aaa05 \
5739f950bcce803d986d189b128861b0 \
@@ -225,7 +229,7 @@ MD5SUM="47bfc192b29252bab6fb436a1b71458d \
47e83dfb22b2531d0aa63d7320294182 \
ba5527be251aede09ca0c45331f0feca \
e5b87a7cd8e16e7f46ee58f0e75c026a \
- aeb725c852e944cabe85cc7a7f2c3741 \
+ f170e46f8a27b917d2a898930a733bf4 \
a42201f337a8d7cd51aae9e5ecad91f0 \
b1c8b47b8fc9077b6a6aadc47c819115 \
5663ea952316dfff411bc1ef78c1979d \
@@ -238,7 +242,7 @@ MD5SUM="47bfc192b29252bab6fb436a1b71458d \
09b520d03e86d50e3ac39d856d5aec32 \
77477373688acb8ff66df5c4f5acd884 \
a1544bff9ea95274369bf38508f8266a \
- d465a926b49a92a0d18ab1d058017c57 \
+ e5d82244e2e26c52316b4b06ac8ae4e5 \
d318084a7a361875006cd156c19db3dc \
067b3ee725d93bc9575a089396d3b54b \
8dab3b3ec00dc56cffde0b0c410d47b5 \
@@ -253,7 +257,7 @@ MD5SUM="47bfc192b29252bab6fb436a1b71458d \
49c7c8d8dff092a63277ed8d8a3b383b \
54cfab480b7a5f7302eadf44129d3f4b \
dd7c80c2d04d2e9ceba82826cf69764d \
- b8a0cdd510c32ee8b6cdd47ba3ea3a4c \
+ 9db1c40cc98e60cc7bd6782249a0ba01 \
cd6875725af793cd82db47d68b00ee93 \
1ea471c67eca6d16b94567f44f43f33b \
56c0a3443b15bf491a2ad5737c138e92 \
@@ -261,11 +265,11 @@ MD5SUM="47bfc192b29252bab6fb436a1b71458d \
bfa2eeb5ad57a1f6d6c3850e84a90344 \
e5b4dc9dafae4028382feb9906201524 \
19a0fe2dd0d3fe5df9e3d8be2a1e3366 \
- 2c4bc5c16b345ce4d4bbf977577fab35 \
+ 0b7994d1256215201bdfb810a357ffa2 \
fe77a3f609b6fd8d5b08f3b2ef14d2ad \
639af0cca65c012e6a028acfb657e417 \
249e03f000851e7478883506cedffc50 \
- 1509d8c3ecae86153ea1e5724d2018c9 \
+ af948c0d86ae82a25dc653465c449b90 \
f1c40b9836035b69e464df711a1d2950 \
4379362bf1be77d47a45c7223a01eead \
73272fe4aadb91d550dca8fc7ead8bf7 \
@@ -274,7 +278,7 @@ MD5SUM="47bfc192b29252bab6fb436a1b71458d \
e53d38f6285cdc1bb509983b218d10d3 \
fba3b040a55c01be7376d3dd5c4d4920 \
23cc9e52c52465f5b225e62ab7cc3457 \
- b57026a52508b4f481c40f241c5e46e5 \
+ fd18fa39d3a1f56b583d84c45092a62b \
ea215774b9829da196e0bf3663758db1 \
84bf26fe4805230859b2138370ba8015 \
0d60bc25ce9a0383bf64efc300f4cb16 \
@@ -282,10 +286,12 @@ MD5SUM="47bfc192b29252bab6fb436a1b71458d \
40e508baeee8cdccbc471489b0f449ff \
7c81e7a61ec172a229d6fdbc553e883d \
b5cf10e268e8a3bee2de8a734104245e \
- 9d375c3f54df74656fa0543c068b861e \
+ fa3630e5867493e09296155763e4f4a0 \
2be566a875ef098dcd1d8a40e42c7d08 \
+ 801b74dcdd5e3ffb56e63a78d9518392 \
+ 39c54f1d98447d48b9c1e0dd345d4316 \
db1ea84c5ee1938888b78e4050dd5cfd \
- eb7a07c42356ca50832d5a7ca0e738d3 \
+ 96b03c27dde2ec45eaaefedf7d76ae3d \
0d4dc4bd76fdb66114874a4afae6834b \
257e573f323c639630b31f147671b627 \
1fbbe598255c0addb31bdfbe3e76420d \
@@ -297,14 +303,15 @@ MD5SUM="47bfc192b29252bab6fb436a1b71458d \
ff6c054468eab826f0dab7cc9a3fe557 \
d0daed97b20f4a6b23c8d4e2ac7b77a8 \
2e504fc2b79dc46f983c960e30be1702 \
- 31afb592628dd2c4da5efbc649fd8066 \
- ad126fb718cd7fc3763016cd2a14c2b2 \
+ 9062c54254d860e7d0bce121981b0f03 \
+ a682ffaef3bb227c7c86574c966147bc \
+ 98b6f812f357ee3c9cf11d31ad98795c \
fdb01eb939ccb5c5ff66970427d22c48 \
03442e847beac2997633c93f7ecb9cc2 \
aecd889de42c8168e1bc97a6f2720d8f \
b4dcac855af5df71f3383d86c4a96b78 \
fd9aa273ad560dedd00ddcf3dbe808ce \
- 921832a39e8a8aac72dfd9ed02227a87 \
+ 09890b5c787af9aedc40f1d75cbe57bb \
e1e7dd5a92eecf2d6a2430313d5b4de5 \
e8cd2956143a3fa2ba14f093d7ccc334 \
fc5f09918af1f97297e928d728e07236 \
@@ -313,38 +320,39 @@ MD5SUM="47bfc192b29252bab6fb436a1b71458d \
448bc61aee07661464d98da7660e9a1d \
17609aa096db0b8f157ca4350317aaa7 \
5ecf56203dda9419751b532d99c3601d \
- 8e2e6734b6acb139eb65c2618fbf7223 \
+ f7e37ccdafce0dcd2001cd78d2c4d169 \
3233400d1bc56e7c78d4d7564d8e5b74 \
6840e02794f8d1a270f10a743f62d8b2 \
- 6bc41c1a00d8876d2ebdcda4054ee4f5 \
+ c4ee6883f04838d193fd03138184a72a \
d961a02195226cfce1a1e23ba5980cb4 \
- 3b298ba1d0e5e75b14765b2c48d52b13 \
+ 95f4b6766a27d814b4e54d1ccb3b7fc9 \
82401c70623ccc1bfc0bcb5c3b0ac8b7 \
0d15e3cf9c34a086912d47c5070f357e \
a69721c73263cd2040e1a5f120b03a6f \
2d8d8b377d144f5e32b4f65a69eb0b24 \
fc60e4ecd18db5e582b9e7dd19dd62e4 \
b4a0a98a54439a5a37952c8879187ee3 \
- 5d44cc9fe4d202d91a978bb21acad716 \
- b5cb7179f7cfe4f22b2eae9650592138 \
- a48bad155fe3ba9bfb2e7c1920bb0d2d \
+ 7adff07da5dc708121d3df9889151d3c \
+ 1d38976243ecc765d0e43f98343518ce \
+ ff1b5cc32f473ab905bb967083e8e5d1 \
540180a044c1a83c751915586ee3a81c \
89b435ff50362dda1abe34a8862cf4ab \
b4a3e97f65acc9e03df7e95defe9b27c \
e0a0f1fa737110ffd0b04af8d1062edd \
- b006529e0475297e0e2346e2a4558931 \
+ 21b43d5721b3a9c16059acb691f4314d \
f5cb2d644e1a5c3cbb9255aa214db9ad \
705c098474edbde60701c80d2669f791 \
e1b37f2526a1f0eed9c0bda62b8095ba \
3a17fdadd69e2e767db3212348f03557 \
- 65d58b65321cd9d5b755429e5fd27d2a \
+ 09d16c0d20d620aa8bb3599cc811bdaa \
+ fa24ed5719d656b7212f8fda727eb098 \
557d2ae2d0ba91790dfa7b2a894807e8 \
781d4ccf5d04c98fa02af207a9639249 \
90253ab52670a0551a533eb78a1f6b10 \
- 3eab1c7442b8411643e65cc15013cd9d \
+ 8508de6b7a06b8dc3ec77eed08868eba \
a8de006fe0c7e373c560dd51599287a8 \
- 73eff52e243dacfa27e2e8b1525268a0 \
- d06ad48ac8b950c7fbe90c82011bcc21 \
+ cc26377eebef938c07887be39a7c9bd5 \
+ 399abfd94c2ac0cb079689ddfa2cd309 \
9d66208e00715217a8c1f2e40efe4a0c \
db6fe956ec67f88412df3a627158a7ba \
3fa52ef3561c641a80bbcfb2c65febbc \
@@ -359,13 +367,13 @@ MD5SUM="47bfc192b29252bab6fb436a1b71458d \
a29fec77b1e07caf7b682b881b676c06 \
580dd7d12690c726da7d5075f3442a74 \
a061ad1db3e0d839725b037ff8be84e7 \
- 18bdc820a80674ed9c63a2716ac41d25 \
- e9571512ea5e2bd7fbfed4be0d50d848 \
- 71647a40ccb0fd8521847da7d8a9af65 \
- 6711d1946b0aee3059bc956dd86cf408 \
- 3fe15799e962c30b24f181d4171eb8a0 \
- 170e1eccf82e1a80b04060c4fd99329e \
- f678473f389fa5e91bf2767becb32d5e \
+ e83ac2d894b5d30b5e239c4f9adb3251 \
+ d081fe3da61178a221036fe2a725da9c \
+ 797615714dd8f6e2781d7de7fd9a5157 \
+ ba7befdb624104c1fd127b5c31189681 \
+ 941184e55173c4862108ba1c4e4ec513 \
+ 68a0780700b88ee0133b0d31bafd1e6a \
+ 90664e6cee0ffbb9fef3710ba815e6a5 \
c900e7dbce808ff8ced375077b17a163 \
db96b50050277bf05a3c68534bbb9586 \
b9e37d5fc4ad28b612b78ad37816684d \
@@ -373,15 +381,15 @@ MD5SUM="47bfc192b29252bab6fb436a1b71458d \
b44489eb4799c4fabac3fceb48de54f7 \
0498c4a11448bfc35dc7bb2caa64c753 \
46bd25f61b8ceaa6a91fbd68e588e1da \
- ab839ba7cdb06278c67f0ff9ad05ab61 \
+ afff460077e49c3ac0b7c958965e8679 \
4396bc1704f7337718352f0e6ec2d391 \
38346bab0933c9eb1e36d22fe4220ba7 \
- 8aa5631ce68ab505b09a7e01fd704f65 \
+ 7a2018d8829ab3ed8b13bf9a2325f2f7 \
6e5896b10ddc995243e45e5482e7ee43 \
bc17188adb6a07610c3a78bfb184ef59 \
ba716045f480186351aef0e77457ff05 \
1628d3f26e3f952d8c43973ade1f2dad \
- c78fded8bcf586e5b389e3366d55f9c0 \
+ 430f3d28d1407a31b3347ec9ec9ebf03 \
331d07cdd036d528ede2f69c7ff0beb6"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
diff --git a/system/apg/apg.SlackBuild b/system/apg/apg.SlackBuild
index 61f96f6319..de7c411387 100644
--- a/system/apg/apg.SlackBuild
+++ b/system/apg/apg.SlackBuild
@@ -28,9 +28,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/arc/arc.SlackBuild b/system/arc/arc.SlackBuild
index 93e8a78b0b..32061c57c8 100644
--- a/system/arc/arc.SlackBuild
+++ b/system/arc/arc.SlackBuild
@@ -22,9 +22,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
@@ -58,11 +55,8 @@ tar xvf $CWD/$PRGNAM-$VERSION.tar.gz || \
tar xvf $CWD/${PRGNAM}_$VERSION.orig.tar.gz
cd $PRGNAM-$VERSION
chown -R root:root .
-find -L . \
- \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
- -o -perm 511 \) -exec chmod 755 {} \; -o \
- \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
- -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
+find -L . -perm /111 -a \! -perm 755 -a -exec chmod 755 {} \+ -o \
+ \! -perm /111 -a \! -perm 644 -a -exec chmod 644 {} \+
sed -i 's,share/man,man,' Makefile
make OPT="$SLKCFLAGS -w -Wl,--allow-multiple-definition" DESTDIR=$PKG PREFIX=/usr all install
diff --git a/system/archivemount/archivemount.SlackBuild b/system/archivemount/archivemount.SlackBuild
index 0542296d5c..047d4c85d0 100644
--- a/system/archivemount/archivemount.SlackBuild
+++ b/system/archivemount/archivemount.SlackBuild
@@ -26,9 +26,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/arj/README b/system/arj/README
index 2cb7b69f23..33855f15c4 100644
--- a/system/arj/README
+++ b/system/arj/README
@@ -3,5 +3,5 @@ arj (Free Software implementation of arj archiver)
A portable version of the ARJ archiver, available for a growing number
of DOS-like and UNIX-like platforms on a variety of architectures.
-This build doesn't conflict with Slackware's unarj package. Unlike unarj,
-arj is capable of creating archives as well as extracting them.
+This build doesn't conflict with Slackware's unarj package. Unlike
+unarj, arj is capable of creating archives as well as extracting them.
diff --git a/system/arj/arj.SlackBuild b/system/arj/arj.SlackBuild
index c4a5841620..e08bee4d67 100644
--- a/system/arj/arj.SlackBuild
+++ b/system/arj/arj.SlackBuild
@@ -26,9 +26,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
@@ -61,11 +58,8 @@ rm -rf $PRGNAM-$VERSION
tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
cd $PRGNAM-$VERSION
chown -R root:root .
-find -L . \
- \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
- -o -perm 511 \) -exec chmod 755 {} \; -o \
- \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
- -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
+find -L . -perm /111 -a \! -perm 755 -a -exec chmod 755 {} \+ -o \
+ \! -perm /111 -a \! -perm 644 -a -exec chmod 644 {} \+
# Use Debian's patches. See https://packages.debian.org/sid/arj. These are
# needed to get the source to build on modern systems, and work correctly
diff --git a/system/arj/arj.info b/system/arj/arj.info
index 57c8b58657..4925854cac 100644
--- a/system/arj/arj.info
+++ b/system/arj/arj.info
@@ -1,7 +1,7 @@
PRGNAM="arj"
VERSION="3.10.22"
HOMEPAGE="http://arj.sourceforge.net/"
-DOWNLOAD="http://downloads.sourceforge.net/project/arj/arj/2.78_3.10%20build%2022/arj-3.10.22.tar.gz"
+DOWNLOAD="http://arj.sourceforge.net/files/arj-3.10.22.tar.gz"
MD5SUM="f263bf3cf6d42a8b7e85b4fb514336d3"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
diff --git a/system/audit/audit.info b/system/audit/audit.info
index 99fa5168ad..0181297e26 100644
--- a/system/audit/audit.info
+++ b/system/audit/audit.info
@@ -1,7 +1,7 @@
PRGNAM="audit"
VERSION="3.0.1"
-HOMEPAGE="http://people.redhat.com/sgrubb/audit/"
-DOWNLOAD="http://people.redhat.com/sgrubb/audit/audit-3.0.1.tar.gz"
+HOMEPAGE="https://people.redhat.com/sgrubb/audit/"
+DOWNLOAD="https://people.redhat.com/sgrubb/audit/audit-3.0.1.tar.gz"
MD5SUM="6a3cfa0dcccb98a85685029236528177"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
diff --git a/system/augeas/augeas.SlackBuild b/system/augeas/augeas.SlackBuild
index 452ddfcaa0..b90c7501cc 100644
--- a/system/augeas/augeas.SlackBuild
+++ b/system/augeas/augeas.SlackBuild
@@ -95,6 +95,8 @@ CXXFLAGS="$SLKCFLAGS" \
make
make install DESTDIR=$PKG
+rm -rf $PKG/usr/lib${LIBDIRSUFFIX}/*.la
+
find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
diff --git a/system/autocutsel/autocutsel.SlackBuild b/system/autocutsel/autocutsel.SlackBuild
index 6bcc6527c2..a5fce772dd 100644
--- a/system/autocutsel/autocutsel.SlackBuild
+++ b/system/autocutsel/autocutsel.SlackBuild
@@ -24,10 +24,12 @@
# Now maintained by B. Watson <yalhcru@gmail.com>
+# 20210827 bkw: update for v0.10.1, remove INSTALL from package.
+
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=autocutsel
-VERSION=${VERSION:-0.10.0}
+VERSION=${VERSION:-0.10.1}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
@@ -40,9 +42,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
@@ -75,11 +74,8 @@ rm -rf $PRGNAM-$VERSION
tar xvf $CWD/$PRGNAM-$VERSION.tar.gz
cd $PRGNAM-$VERSION
chown -R root:root .
-find -L . \
- \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
- -o -perm 511 \) -exec chmod 755 {} \; -o \
- \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
- -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
+find -L . -perm /111 -a \! -perm 755 -a -exec chmod 755 {} \+ -o \
+ \! -perm /111 -a \! -perm 644 -a -exec chmod 644 {} \+
CFLAGS="$SLKCFLAGS" \
CXXFLAGS="$SLKCFLAGS" \
@@ -101,7 +97,7 @@ for i in $PRGNAM cutsel; do
done
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
-cp -a AUTHORS COPYING ChangeLog INSTALL README $PKG/usr/doc/$PRGNAM-$VERSION
+cp -a AUTHORS COPYING ChangeLog README $PKG/usr/doc/$PRGNAM-$VERSION
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
mkdir -p $PKG/install
diff --git a/system/autocutsel/autocutsel.info b/system/autocutsel/autocutsel.info
index e795961444..7509bddbd2 100644
--- a/system/autocutsel/autocutsel.info
+++ b/system/autocutsel/autocutsel.info
@@ -1,8 +1,8 @@
PRGNAM="autocutsel"
-VERSION="0.10.0"
-HOMEPAGE="http://www.nongnu.org/autocutsel"
-DOWNLOAD="https://github.com/sigmike/autocutsel/releases/download/0.10.0/autocutsel-0.10.0.tar.gz"
-MD5SUM="7d5b96e5f7b79b883d8350f104043366"
+VERSION="0.10.1"
+HOMEPAGE="https://www.nongnu.org/autocutsel"
+DOWNLOAD="https://github.com/sigmike/autocutsel/releases/download/0.10.1/autocutsel-0.10.1.tar.gz"
+MD5SUM="4e891b51745891d3367f085ff84610de"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
diff --git a/system/bat/bat.SlackBuild b/system/bat/bat.SlackBuild
index 2d57c20192..7d1ec4ac0c 100644
--- a/system/bat/bat.SlackBuild
+++ b/system/bat/bat.SlackBuild
@@ -3,6 +3,7 @@
# Slackware build script for bat
# Copyright 2019-2021 Benjamin Trigona-Harany <slackbuilds@jaxartes.net>
+# Copyright 2021 Erich Ritz, Jenks, Oklahoma, USA
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@@ -25,7 +26,7 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=bat
-VERSION=${VERSION:-0.18.1}
+VERSION=${VERSION:-0.18.3}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
@@ -87,13 +88,13 @@ cd $PRGNAM-$VERSION
# configuration tells cargo to use the configured directory
# for dependencies intead of downloading from crates.io
mkdir .cargo
-cat << EOF >> .cargo/config
+cat << EOF >> .cargo/config.toml
+[source]
[source.crates-io]
-registry = 'https://github.com/rust-lang/crates.io-index'
-replace-with = 'vendored-sources'
+replace-with = "vendored-sources"
[source.vendored-sources]
-directory = '$(pwd)/vendor'
+directory = "vendor"
EOF
# deps and versions come from Cargo.lock
@@ -101,15 +102,31 @@ mkdir vendor
(
cd vendor
- grep -h -A 3 "\[\[package\]\]" $(find ../ -maxdepth 1 -mindepth 1 -name Cargo.lock | tr '\n' ' ') | \
- sed 's/[[:space:]]*=[[:space:]]*/=/g;s/^--//;s/^\[\[/--\n[[/' | \
- awk 'BEGIN { RS = "--\n" ; FS="\n" } { print $2, $3, $4 }' | sed 's/"//g;s/name=//;s/ version=/=/' | \
- grep crates\.io-index | sed 's/ source=.*$//' | sort -u | while read -r dep ; do
-
+ grep -h -A 4 "\[\[package\]\]" \
+ $(find "../" -maxdepth 1 -mindepth 1 -name Cargo.lock | tr '\n' ' ') | \
+ sed 's/[[:space:]]*=[[:space:]]*/=/g;s/^--//;s/^\[\[/--\n[[/' | \
+ awk 'BEGIN { RS = "--\n" ; FS="\n" } { print $2, $3, $4, $5 }' | \
+ sed 's/"//g;s/name=//;s/ version=/=/' | \
+ grep " source=" | \
+ sed 's/ dependencies=.*$//' | \
+ sed 's/ source=[^ ]*//' | \
+ sed 's/ checksum=/=/' | \
+ sort -u | \
+ while read -r dep ; do
+
+ cksum="$(printf "%s\n" "$dep" | cut -d= -f3)"
ver="$(printf "%s\n" "$dep" | cut -d= -f2)"
dep="$(printf "%s\n" "$dep" | cut -d= -f1)"
- tar xvf $CWD/$dep-$ver.crate
+ CRATE_FILE=$CWD/$dep-$ver.crate
+
+ if [ -z "$cksum" ] ; then
+ mkdir $dep-$ver
+ tar xvf $CRATE_FILE -C $dep-$ver --strip-components=1
+ cksum="null"
+ else
+ tar xvf $CRATE_FILE
+ fi
touch $dep-$ver/.cargo-ok
@@ -124,9 +141,7 @@ mkdir vendor
) | sed '$ s/,$//'
printf " },\n"
- printf ' "package": "'
-
- sha256sum "$CWD/$dep-$ver.crate" | cut -f1 -d' ' | sed 's/$/"/'
+ printf ' "package": "%s"' "$cksum"
printf "}\n"
} | python -c "import sys, json; data = sys.stdin.read(); print json.dumps(json.loads(data), sort_keys=True, indent=4, separators=(',', ' : '))" > $dep-$ver/.cargo-checksum.json
@@ -153,7 +168,7 @@ find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | gr
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
cp -a -r \
- LICENSE-APACHE LICENSE-MIT README.md \
+ LICENSE-APACHE LICENSE-MIT README.md CHANGELOG.md CONTRIBUTING.md \
$PKG/usr/doc/$PRGNAM-$VERSION
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
diff --git a/system/bat/bat.info b/system/bat/bat.info
index dd3326b160..c6b38d17df 100644
--- a/system/bat/bat.info
+++ b/system/bat/bat.info
@@ -1,23 +1,22 @@
PRGNAM="bat"
-VERSION="0.18.1"
+VERSION="0.18.3"
HOMEPAGE="https://github.com/sharkdp/bat"
-DOWNLOAD="https://github.com/sharkdp/bat/archive/v0.18.1/bat-0.18.1.tar.gz \
+DOWNLOAD="https://github.com/sharkdp/bat/archive/v0.18.3/bat-0.18.3.tar.gz \
https://crates-io.s3-us-west-1.amazonaws.com/crates/adler/adler-1.0.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/aho-corasick/aho-corasick-0.7.18.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/ansi_colours/ansi_colours-1.0.2.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/ansi_colours/ansi_colours-1.0.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/ansi_term/ansi_term-0.11.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/ansi_term/ansi_term-0.12.1.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/assert_cmd/assert_cmd-1.0.3.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/assert_cmd/assert_cmd-1.0.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/atty/atty-0.2.14.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/autocfg/autocfg-1.0.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/base64/base64-0.13.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/bat/bat-0.18.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/bincode/bincode-1.3.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/bit-set/bit-set-0.5.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/bit-vec/bit-vec-0.6.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/bitflags/bitflags-1.2.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/bstr/bstr-0.2.16.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/bugreport/bugreport-0.4.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/bugreport/bugreport-0.4.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/byteorder/byteorder-1.4.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/cc/cc-1.0.67.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/cfg-if/cfg-if-1.0.0.crate \
@@ -33,12 +32,12 @@ DOWNLOAD="https://github.com/sharkdp/bat/archive/v0.18.1/bat-0.18.1.tar.gz \
https://crates-io.s3-us-west-1.amazonaws.com/crates/doc-comment/doc-comment-0.3.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/dtoa/dtoa-0.4.8.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/encode_unicode/encode_unicode-0.3.6.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/encoding/encoding-0.2.33.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/encoding-index-japanese/encoding-index-japanese-1.20141219.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/encoding-index-korean/encoding-index-korean-1.20141219.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/encoding-index-simpchinese/encoding-index-simpchinese-1.20141219.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/encoding-index-singlebyte/encoding-index-singlebyte-1.20141219.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/encoding-index-tradchinese/encoding-index-tradchinese-1.20141219.5.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/encoding/encoding-0.2.33.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/encoding_index_tests/encoding_index_tests-0.1.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/error-chain/error-chain-0.12.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/fancy-regex/fancy-regex-0.3.5.crate \
@@ -47,11 +46,12 @@ DOWNLOAD="https://github.com/sharkdp/bat/archive/v0.18.1/bat-0.18.1.tar.gz \
https://crates-io.s3-us-west-1.amazonaws.com/crates/fnv/fnv-1.0.7.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/form_urlencoded/form_urlencoded-1.0.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/getrandom/getrandom-0.2.2.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/git-version/git-version-0.3.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/git-version-macro/git-version-macro-0.3.4.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/git2/git2-0.13.19.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/git-version/git-version-0.3.4.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/git2/git2-0.13.20.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/glob/glob-0.3.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/globset/globset-0.4.6.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/globset/globset-0.4.8.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/grep-cli/grep-cli-0.1.6.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/hashbrown/hashbrown-0.9.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/hermit-abi/hermit-abi-0.1.18.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/idna/idna-0.2.3.crate \
@@ -61,8 +61,8 @@ DOWNLOAD="https://github.com/sharkdp/bat/archive/v0.18.1/bat-0.18.1.tar.gz \
https://crates-io.s3-us-west-1.amazonaws.com/crates/jobserver/jobserver-0.1.22.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/lazy_static/lazy_static-1.4.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/lazycell/lazycell-1.3.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/libc/libc-0.2.94.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/libgit2-sys/libgit2-sys-0.12.20+1.1.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/libc/libc-0.2.95.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/libgit2-sys/libgit2-sys-0.12.21+1.1.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/libz-sys/libz-sys-1.1.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/line-wrap/line-wrap-0.1.1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/linked-hash-map/linked-hash-map-0.5.4.crate \
@@ -70,8 +70,9 @@ DOWNLOAD="https://github.com/sharkdp/bat/archive/v0.18.1/bat-0.18.1.tar.gz \
https://crates-io.s3-us-west-1.amazonaws.com/crates/log/log-0.4.14.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/matches/matches-0.1.8.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/memchr/memchr-2.4.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/memoffset/memoffset-0.6.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/miniz_oxide/miniz_oxide-0.4.4.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/nix/nix-0.20.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/nix/nix-0.21.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/normalize-line-endings/normalize-line-endings-0.3.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/num-integer/num-integer-0.1.44.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/num-traits/num-traits-0.2.14.crate \
@@ -85,9 +86,9 @@ DOWNLOAD="https://github.com/sharkdp/bat/archive/v0.18.1/bat-0.18.1.tar.gz \
https://crates-io.s3-us-west-1.amazonaws.com/crates/pkg-config/pkg-config-0.3.19.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/plist/plist-1.1.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/ppv-lite86/ppv-lite86-0.2.10.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/predicates/predicates-1.0.8.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/predicates-core/predicates-core-1.0.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/predicates-tree/predicates-tree-1.0.2.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/predicates/predicates-1.0.8.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/proc-macro-hack/proc-macro-hack-0.5.19.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/proc-macro2/proc-macro2-1.0.26.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/quote/quote-1.0.9.crate \
@@ -97,16 +98,16 @@ DOWNLOAD="https://github.com/sharkdp/bat/archive/v0.18.1/bat-0.18.1.tar.gz \
https://crates-io.s3-us-west-1.amazonaws.com/crates/rand_hc/rand_hc-0.3.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/redox_syscall/redox_syscall-0.2.8.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/redox_users/redox_users-0.4.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/regex/regex-1.5.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/regex-automata/regex-automata-0.1.9.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/regex-syntax/regex-syntax-0.6.25.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/regex/regex-1.5.4.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/remove_dir_all/remove_dir_all-0.5.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/ryu/ryu-1.0.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/safemem/safemem-0.3.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/same-file/same-file-1.0.6.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/scopeguard/scopeguard-1.1.0.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/semver/semver-0.11.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/semver-parser/semver-parser-0.10.2.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/semver/semver-0.11.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/serde/serde-1.0.126.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/serde_derive/serde_derive-1.0.126.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/serde_json/serde_json-1.0.64.crate \
@@ -123,6 +124,7 @@ DOWNLOAD="https://github.com/sharkdp/bat/archive/v0.18.1/bat-0.18.1.tar.gz \
https://crates-io.s3-us-west-1.amazonaws.com/crates/sys-info/sys-info-0.9.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/tempfile/tempfile-3.2.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/term_size/term_size-0.3.2.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/termcolor/termcolor-1.1.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/terminal_size/terminal_size-0.1.16.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/textwrap/textwrap-0.11.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/tinyvec/tinyvec-1.2.0.crate \
@@ -141,29 +143,28 @@ DOWNLOAD="https://github.com/sharkdp/bat/archive/v0.18.1/bat-0.18.1.tar.gz \
https://crates-io.s3-us-west-1.amazonaws.com/crates/walkdir/walkdir-2.3.2.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/wasi/wasi-0.10.2+wasi-snapshot-preview1.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/wild/wild-2.0.4.crate \
- https://crates-io.s3-us-west-1.amazonaws.com/crates/winapi/winapi-0.3.9.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/winapi-i686-pc-windows-gnu/winapi-i686-pc-windows-gnu-0.4.0.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/winapi-util/winapi-util-0.1.5.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/winapi-x86_64-pc-windows-gnu/winapi-x86_64-pc-windows-gnu-0.4.0.crate \
+ https://crates-io.s3-us-west-1.amazonaws.com/crates/winapi/winapi-0.3.9.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/xml-rs/xml-rs-0.8.3.crate \
https://crates-io.s3-us-west-1.amazonaws.com/crates/yaml-rust/yaml-rust-0.4.5.crate"
-MD5SUM="350d39d4e5b10f8c5bcdd93d96ca6794 \
+MD5SUM="df1b1e7cc3ea8922f6a287b5c2abb413 \
669215548c64019c08c92b2c1afd3deb \
425b8fdf70df59998d9b7c89083e48d1 \
- 3b493a3c9dcd266b3b682e2c2f2191e1 \
+ 7a42a6dfbd0d20b9c00ea115cc37af4a \
294a49d3c53865fa7ac5d0ce2f5d5735 \
f44e8d1d2e61974b268852797530ea41 \
- 6bd91b6b8d9a78a24535d0ed8c738a6c \
+ b51fc6924f92ea67ab4eef8b54de45ec \
142cb4b9a653e56e56311f0c883b8582 \
c6443ec8d007c729ba5482008d0c864d \
80a2c27647a6acb1890a3a7de8fded72 \
- d9578265dd73c47de996a1008caf5903 \
b9beac7e75b4986031a89562c26eb553 \
8f8acc3c1caff2043085a0cc28a92757 \
45a867175c81501378699f80724393c0 \
6799c26a7eacaf8e58d3e45c6c5add89 \
a24bd43eb77d74bb2820e5a3f336f7bc \
- fcaaf75ea5cfa33c9a8a031d64fcf6ee \
+ 9a3828304994821308f32640f93688bb \
1e704be5ddde9d6b5383ef1035309f91 \
8637708206e07c0b9e726c7b2f4412d6 \
74634128440dbc3766bda76fdf0aaa05 \
@@ -179,12 +180,12 @@ MD5SUM="350d39d4e5b10f8c5bcdd93d96ca6794 \
dd1e49c76e9d5853e673a3b41ba02917 \
77477373688acb8ff66df5c4f5acd884 \
95a243b2d7c30018a643e218b3c5d693 \
- 1cdd23edc54b385ee5cfb6a0f9f52f17 \
c19b47edfeea6760da864066bba50208 \
bb17317266b63ce2a7eb7b8a47f35594 \
1618bf8d183d5cee0b6db1392a8f874b \
0dbb2c3d83adb1fa4f17ac94e2bef0dc \
afdb4c49775dbcd9c76763052433d370 \
+ 1cdd23edc54b385ee5cfb6a0f9f52f17 \
5c31515f4fc8fc5167a5b64f816e915e \
da699c4c8e4c153cbdb9fb0ef3fb3056 \
480f00b3768504ade60944b9b340bc67 \
@@ -193,11 +194,12 @@ MD5SUM="350d39d4e5b10f8c5bcdd93d96ca6794 \
8dab3b3ec00dc56cffde0b0c410d47b5 \
7ee8703970c3fa6a2e37893de742824b \
b8a0cdd510c32ee8b6cdd47ba3ea3a4c \
- aeffd9eadfab0c1399895bef51409022 \
f765fe879d74caa83770d27825d42575 \
- e925f5d85287cfeec14ca7521619580d \
+ aeffd9eadfab0c1399895bef51409022 \
+ 7f3b6bf711474f2e46abcdda7b614e8a \
e7c07242a95ee1df865efe9534e10a34 \
- 1b94f32581a557963eecb29761e9c0eb \
+ 74f2ffc4199d52c2c0349022235ca09f \
+ ba1f74c9fe8c49c1a8ee1b1d8595d6b8 \
58285dfb5134c5df5503066a20dc9d2c \
2c4bc5c16b345ce4d4bbf977577fab35 \
f50aaf5171cbc0327f8d18a4ec7405fb \
@@ -207,8 +209,8 @@ MD5SUM="350d39d4e5b10f8c5bcdd93d96ca6794 \
98622e4faf3933b52243b6742de8d75f \
fba3b040a55c01be7376d3dd5c4d4920 \
23cc9e52c52465f5b225e62ab7cc3457 \
- b57026a52508b4f481c40f241c5e46e5 \
- a9f62403ba704fe3aa6aba2ecf125199 \
+ dc1495b6997f34909139d1bf551b8d2b \
+ 672e362e78ddabea6fdc622983961dde \
9160664d20c024783323f5b90ca74d2d \
651dd38020e02806ccadcc41df89c7dc \
0d60bc25ce9a0383bf64efc300f4cb16 \
@@ -216,8 +218,9 @@ MD5SUM="350d39d4e5b10f8c5bcdd93d96ca6794 \
40e508baeee8cdccbc471489b0f449ff \
7916dcd738a8fa6a2798754c20d6e146 \
9d375c3f54df74656fa0543c068b861e \
+ 39c54f1d98447d48b9c1e0dd345d4316 \
084881559fa038861d17e7b0aa76f54e \
- 2e504fc2b79dc46f983c960e30be1702 \
+ a5b98e74c0919228a029ad0ae729c928 \
f9ddf92ded75c1df47b2dd1379a482fd \
a8ec1126ef06244ac1e3773981a005f1 \
c0e036fd990d0c9cae11b5876a5cb572 \
@@ -231,9 +234,9 @@ MD5SUM="350d39d4e5b10f8c5bcdd93d96ca6794 \
448bc61aee07661464d98da7660e9a1d \
899b172855b10f2e76eea3ecc6314a7d \
a4ff7abd41c57dfd24bbd4b50edb848f \
- 0b64bd1f832710eb571c97ee0b7e2388 \
30d783a004d6ae43913983d49b8466c9 \
59425b318d7a80253445671a9fda0aa4 \
+ 0b64bd1f832710eb571c97ee0b7e2388 \
c7c38eb603bed6f42edbc4294806a44a \
8e2e6734b6acb139eb65c2618fbf7223 \
3233400d1bc56e7c78d4d7564d8e5b74 \
@@ -243,16 +246,16 @@ MD5SUM="350d39d4e5b10f8c5bcdd93d96ca6794 \
69e9436d5c9889a6fdf199dfc5c3d3fe \
6bc41c1a00d8876d2ebdcda4054ee4f5 \
d961a02195226cfce1a1e23ba5980cb4 \
- 4606e4a248df4d70509afded817aca14 \
3b298ba1d0e5e75b14765b2c48d52b13 \
82401c70623ccc1bfc0bcb5c3b0ac8b7 \
+ 4606e4a248df4d70509afded817aca14 \
0538d1da369f3e3f0412aa4d735c1b61 \
a69721c73263cd2040e1a5f120b03a6f \
994b165f971ecfc09dc13fca8d394691 \
2d8d8b377d144f5e32b4f65a69eb0b24 \
b4a0a98a54439a5a37952c8879187ee3 \
- d2cc4e584ed64165fc56d2c9081eb3ee \
42408be0352a76b14f1e77a6b8858a77 \
+ d2cc4e584ed64165fc56d2c9081eb3ee \
7b99a756f9d302ca306431aabd891530 \
082d0ac393ba1bfdd141fd37ae7349d8 \
a48bad155fe3ba9bfb2e7c1920bb0d2d \
@@ -269,6 +272,7 @@ MD5SUM="350d39d4e5b10f8c5bcdd93d96ca6794 \
2f9e2fcf69a6ac528ad54214b51fdd10 \
6e328718765f2352dd34f10215488fbb \
73d602cc41e3e431bf4fabd129ae1616 \
+ ebdff467249aa3dca005a441dc824236 \
62a72aa48fde11aa7b0daf7788009ca5 \
a8de006fe0c7e373c560dd51599287a8 \
9750b80eb8a2fc79cb20c86752503ddd \
@@ -287,14 +291,14 @@ MD5SUM="350d39d4e5b10f8c5bcdd93d96ca6794 \
580dd7d12690c726da7d5075f3442a74 \
a061ad1db3e0d839725b037ff8be84e7 \
95491f9095e26cbd501d6aadc7322e1c \
- 0498c4a11448bfc35dc7bb2caa64c753 \
db96b50050277bf05a3c68534bbb9586 \
b9e37d5fc4ad28b612b78ad37816684d \
09de9d01e7331ff3da11f58be8bef0df \
+ 0498c4a11448bfc35dc7bb2caa64c753 \
c78fded8bcf586e5b389e3366d55f9c0 \
331d07cdd036d528ede2f69c7ff0beb6"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
-MAINTAINER="Benjamin Trigona-Harany"
-EMAIL="slackbuilds@jaxartes.net"
+MAINTAINER="Erich Ritz"
+EMAIL="erich.public@protonmail.com"
diff --git a/system/bitmapfont2ttf/README b/system/bitmapfont2ttf/README
index 1c9b9a50e0..f3470e7680 100644
--- a/system/bitmapfont2ttf/README
+++ b/system/bitmapfont2ttf/README
@@ -6,7 +6,7 @@ The resulting font retains its "pixelated" look when scaled up to any
size.
bitmapfont2ttf is a bit picky about the BDF fonts it will accept as
-input. This build includes a patch that allows it to work with fonts
+input. This build includes a patch that allows it to work with fonts
produced by psf2bdf (from psftools). The patch is applied by default,
but you can export PRISTINE=yes in the environment if you really don't
want it.
diff --git a/system/bitmapfont2ttf/bitmapfont2ttf.SlackBuild b/system/bitmapfont2ttf/bitmapfont2ttf.SlackBuild
index 6e0f5e9bf1..2c1906f5c2 100644
--- a/system/bitmapfont2ttf/bitmapfont2ttf.SlackBuild
+++ b/system/bitmapfont2ttf/bitmapfont2ttf.SlackBuild
@@ -28,9 +28,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/bitmapfont2ttf/bitmapfont2ttf.info b/system/bitmapfont2ttf/bitmapfont2ttf.info
index a245e0f4b4..aa48c7a160 100644
--- a/system/bitmapfont2ttf/bitmapfont2ttf.info
+++ b/system/bitmapfont2ttf/bitmapfont2ttf.info
@@ -5,6 +5,6 @@ DOWNLOAD="https://slackware.uk/~urchlay/src/bitmapfont2ttf-20200215_03529d2.tar.
MD5SUM="5f4ab36a5d56c79e28ce38841f063bdc"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
-REQUIRES=""
+REQUIRES="fontforge"
MAINTAINER="B. Watson"
EMAIL="yalhcru@gmail.com"
diff --git a/system/cbmbasic/README b/system/cbmbasic/README
index 8fb257cf98..84386a8201 100644
--- a/system/cbmbasic/README
+++ b/system/cbmbasic/README
@@ -1,8 +1,9 @@
cbmbasic (Commodore BASIC V2 as a scripting language)
Commodore BASIC (cbmbasic) is a 100% compatible version of Commodore's
-version of Microsoft 6502 BASIC as found on the Commodore 64. You can use
-it in interactive mode or pass a BASIC file as a command line parameter.
+version of Microsoft 6502 BASIC as found on the Commodore 64. You
+can use it in interactive mode or pass a BASIC file as a command line
+parameter.
This does not emulate 6502 code; all code is completely native. On a
1GHz CPU you get about 1000x speed compared to a 1MHz 6502.
diff --git a/system/cbmbasic/cbmbasic.SlackBuild b/system/cbmbasic/cbmbasic.SlackBuild
index 38bed865f5..61fc0de0a4 100644
--- a/system/cbmbasic/cbmbasic.SlackBuild
+++ b/system/cbmbasic/cbmbasic.SlackBuild
@@ -6,6 +6,8 @@
# Licensed under the WTFPL. See http://www.wtfpl.net/txt/copying/ for details.
+# 20210827 bkw: fix build on -current
+
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=cbmbasic
@@ -22,9 +24,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
@@ -57,13 +56,10 @@ rm -rf $PRGNAM-$VERSION
tar xvf $CWD/$PRGNAM-$VERSION.tgz
cd $PRGNAM-$VERSION
chown -R root:root .
-find -L . \
- \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
- -o -perm 511 \) -exec chmod 755 {} \; -o \
- \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
- -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
+find -L . -perm /111 -a \! -perm 755 -a -exec chmod 755 {} \+ -o \
+ \! -perm /111 -a \! -perm 644 -a -exec chmod 644 {} \+
-make CFLAGS="$SLKCFLAGS" LDFLAGS="-L/usr/lib$LIBDIRSUFFIX"
+make CFLAGS="$SLKCFLAGS -fcommon" LDFLAGS="-L/usr/lib$LIBDIRSUFFIX"
mkdir -p $PKG/usr/bin
install -s -m0755 $PRGNAM $PKG/usr/bin
diff --git a/system/cbmbasic/cbmbasic.info b/system/cbmbasic/cbmbasic.info
index ae226159f9..e13024afb4 100644
--- a/system/cbmbasic/cbmbasic.info
+++ b/system/cbmbasic/cbmbasic.info
@@ -1,7 +1,7 @@
PRGNAM="cbmbasic"
VERSION="1.0"
HOMEPAGE="http://cbmbasic.sourceforge.net/"
-DOWNLOAD="http://downloads.sourceforge.net/project/cbmbasic/cbmbasic/1.0/cbmbasic-1.0.tgz"
+DOWNLOAD="https://downloads.sourceforge.net/project/cbmbasic/cbmbasic/1.0/cbmbasic-1.0.tgz"
MD5SUM="966cf93950809c3eace244af702cf895"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
diff --git a/system/ccd2cue/ccd2cue.SlackBuild b/system/ccd2cue/ccd2cue.SlackBuild
index 69c2ba5aef..f47fa878d4 100644
--- a/system/ccd2cue/ccd2cue.SlackBuild
+++ b/system/ccd2cue/ccd2cue.SlackBuild
@@ -22,9 +22,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/ccd2cue/ccd2cue.info b/system/ccd2cue/ccd2cue.info
index 02c096e670..4eed2ed32d 100644
--- a/system/ccd2cue/ccd2cue.info
+++ b/system/ccd2cue/ccd2cue.info
@@ -1,7 +1,7 @@
PRGNAM="ccd2cue"
VERSION="0.5"
HOMEPAGE="https://www.gnu.org/software/ccd2cue/"
-DOWNLOAD="http://ftpmirror.gnu.org/ccd2cue/ccd2cue-0.5.tar.gz"
+DOWNLOAD="https://ftpmirror.gnu.org/ccd2cue/ccd2cue-0.5.tar.gz"
MD5SUM="565eb34e3ab5331ee5aab2fe215118aa"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
diff --git a/system/ciopfs/ciopfs.SlackBuild b/system/ciopfs/ciopfs.SlackBuild
index 3be5a33d0e..88cb9f58e7 100644
--- a/system/ciopfs/ciopfs.SlackBuild
+++ b/system/ciopfs/ciopfs.SlackBuild
@@ -44,9 +44,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/ciopfs/ciopfs.info b/system/ciopfs/ciopfs.info
index 64b2a2ee75..d53ecef15c 100644
--- a/system/ciopfs/ciopfs.info
+++ b/system/ciopfs/ciopfs.info
@@ -1,7 +1,7 @@
PRGNAM="ciopfs"
VERSION="0.4"
-HOMEPAGE="http://www.brain-dump.org/projects/ciopfs/"
-DOWNLOAD="http://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz"
+HOMEPAGE="https://www.brain-dump.org/projects/ciopfs/"
+DOWNLOAD="https://www.brain-dump.org/projects/ciopfs/ciopfs-0.4.tar.gz"
MD5SUM="1798fc043034f292efd887c05fc4ea1e"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
diff --git a/system/clamav/clamav.SlackBuild b/system/clamav/clamav.SlackBuild
index 53a153581f..aa16be14ab 100644
--- a/system/clamav/clamav.SlackBuild
+++ b/system/clamav/clamav.SlackBuild
@@ -30,7 +30,7 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=clamav
-VERSION=${VERSION:-0.103.3}
+VERSION=${VERSION:-0.104.0}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
@@ -88,26 +88,6 @@ elif ! getent passwd clamav 2>&1 > /dev/null; then
bailout ;
fi
-# check if json-c is there: if it is, build over it to enable
-# the file properties collection and analysis feature
-# http://blog.clamav.net/2014/11/intro-to-collection-and-analysis-of.html
-if pkg-config --exists json-c ; then
- with_jsonc="--with-libjson"
-else
- with_jsonc=""
-fi
-
-# Some people don't have sendmail installed: don't build milter stuff
-# in this case.
-# This is your call, not having sendmail is *UNSUPPORTED*
-if [ ! -f /usr/lib$LIBDIRSUFFIX/libmilter.a ]; then
- milter="dis"
- milter_cf=""
-else
- milter="en"
- milter_cf="clamav-milter"
-fi
-
set -e
rm -rf $PKG
@@ -153,32 +133,27 @@ sed \
-e "s/^\#ExitOnOOM/ExitOnOOM/" \
-i etc/clamd.conf.sample || exit 1
-autoreconf -fi
-
-CFLAGS="$SLKCFLAGS" \
-CXXFLAGS="$SLKCFLAGS" \
-./configure \
- --prefix=/usr \
- --libdir=/usr/lib${LIBDIRSUFFIX} \
- --localstatedir=/var \
- --sysconfdir=/etc \
- --mandir=/usr/man \
- --with-user=clamav \
- --with-group=clamav \
- --with-dbdir=/var/lib/clamav \
- --${milter}able-milter \
- --enable-id-check \
- --enable-clamdtop \
- --disable-static \
- --disable-experimental \
- $with_jsonc \
- --build=$ARCH-slackware-linux
-
-make V=1
-make install DESTDIR=$PKG
+mkdir -p build
+cd build
+ cmake \
+ -DCMAKE_C_FLAGS:STRING="$SLKCFLAGS" \
+ -DCMAKE_CXX_FLAGS:STRING="$SLKCFLAGS" \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DCMAKE_INSTALL_FULL_LIBDIR=/usr/lib$LIBDIRSUFFIX \
+ -DAPP_CONFIG_DIRECTORY=/etc \
+ -DENABLE_MILTER=ON \
+ -DENABLE_SYSTEMD=OFF \
+ -DENABLE_TESTS=OFF \
+ -DCMAKE_BUILD_TYPE=Release ..
+ make
+ make install DESTDIR=$PKG
+cd ..
+
+mv $PKG/usr/share/man $PKG/usr/man
+rm -fR $PKG/usr/share
# Prepare the config files:
-for cf in clamd freshclam $milter_cf; do
+for cf in clamd freshclam clamav-milter; do
mv $PKG/etc/$cf.conf.sample $PKG/etc/$cf.conf.new
done
@@ -196,10 +171,8 @@ chmod 0775 $PKG/var/lib/clamav
# Fixup some ownership and permissions issues
chown -R root:root $PKG
chmod -R o-w $PKG
-if [ "$milter" = "en" ]; then
- chown clamav $PKG/usr/sbin/clamav-milter
- chmod 4700 $PKG/usr/sbin/clamav-milter
-fi
+chown clamav $PKG/usr/sbin/clamav-milter
+chmod 4700 $PKG/usr/sbin/clamav-milter
touch $PKG/var/lib/clamav/main.cvd $PKG/var/lib/clamav/daily.cvd
chmod 0660 $PKG/var/lib/clamav/*
@@ -212,7 +185,7 @@ chmod 0660 $PKG/var/log/clamav/clamd.log.new \
chown -R clamav:clamav $PKG/var/lib/clamav $PKG/var/log/clamav \
$PKG/var/run/clamav
-find $PKG | xargs file | grep -e "executable" -e "shared object" | grep ELF \
+find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
# Compress the man page(s)
diff --git a/system/clamav/clamav.info b/system/clamav/clamav.info
index e01fcb08e8..575dc9e787 100644
--- a/system/clamav/clamav.info
+++ b/system/clamav/clamav.info
@@ -1,8 +1,8 @@
PRGNAM="clamav"
-VERSION="0.103.3"
+VERSION="0.104.0"
HOMEPAGE="https://www.clamav.net/"
-DOWNLOAD="https://www.clamav.net/downloads/production/clamav-0.103.3.tar.gz"
-MD5SUM="f8dcf678953f6af056ddd5917bcc50c3"
+DOWNLOAD="https://www.clamav.net/downloads/production/clamav-0.104.0.tar.gz"
+MD5SUM="3f4789c09f5a35e9ea580edd5c3e54b6"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
diff --git a/system/cnijfilter2/cnijfilter2.SlackBuild b/system/cnijfilter2/cnijfilter2.SlackBuild
index fd467c601a..3f573cc37d 100644
--- a/system/cnijfilter2/cnijfilter2.SlackBuild
+++ b/system/cnijfilter2/cnijfilter2.SlackBuild
@@ -25,13 +25,13 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=cnijfilter2
-VERSION=${VERSION:-5.90.1}
+VERSION=${VERSION:-6.10.1}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
SRCNAM=$PRGNAM-source
-SRCVERSION=5.90-1
+SRCVERSION=6.10-1
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
@@ -56,18 +56,15 @@ OUTPUT=${OUTPUT:-/tmp}
if [ "$ARCH" = "i586" ]; then
SLKCFLAGS="-O2 -march=i586 -mtune=i686"
LIBDIRSUFFIX=""
- LDFLAGS="-L$TMP/${SRCNAM}-${SRCVERSION}/com/libs_bin32"
- BITS="i386"
+ BITS="32"
elif [ "$ARCH" = "i686" ]; then
SLKCFLAGS="-O2 -march=i686 -mtune=i686"
LIBDIRSUFFIX=""
- LDFLAGS="-L$TMP/${SRCNAM}-${SRCVERSION}/com/libs_bin32"
- BITS="i386"
+ BITS="32"
elif [ "$ARCH" = "x86_64" ]; then
SLKCFLAGS="-O2 -fPIC"
LIBDIRSUFFIX="64"
- LDFLAGS="-L$TMP/${SRCNAM}-${SRCVERSION}/com/libs_bin64"
- BITS="amd64"
+ BITS="64"
else
echo "Package for $(uname -m) architecture is not available."
exit 1
@@ -92,40 +89,66 @@ find -L . \
\( -type f \! -name autogen.sh \) \
-exec chmod 644 {} \;
+patch -p1 < $CWD/gcc10.patch
+
+for dir in cmdtocanonij2 cmdtocanonij3 ; do
+ pushd $dir
+ ./autogen.sh --prefix=/usr --datadir=/usr/share LDFLAGS="-L../../com/libs_bin${BITS}"
+ make
+ popd
+done
+
+pushd cnijbe2
+ ./autogen.sh --prefix=/usr --enable-progpath=/usr/bin
+ make
+popd
+
+pushd lgmon3
+ ./autogen.sh --prefix=/usr --enable-libpath=/usr/lib${LIBDIRSUFFIX}/bjlib2 --enable-progpath=/usr/bin \
+ --datadir=/usr/share LDFLAGS="-L../../com/libs_bin${BITS}"
+ make
+popd
+
+pushd rastertocanonij
+ ./autogen.sh --prefix=/usr --enable-progpath=/usr/bin
+ make
+popd
+
+for dir in tocanonij tocnpwg ; do
+ pushd $dir
+ ./autogen.sh --prefix=/usr
+ make
+ popd
+done
+
common_pkg="cmdtocanonij2 cmdtocanonij3 cnijbe2 lgmon3 rastertocanonij tocanonij tocnpwg"
for dir in $common_pkg; do
- cd $dir
- ./autogen.sh --prefix=/usr LDFLAGS="$LDFLAGS"
- make
- make install-strip DESTDIR=$PKG
- cd ..
+ pushd $dir
+ make install DESTDIR=$PKG
+ popd
done
-cd lgmon3
- ./autogen.sh --prefix=/usr --enable-libpath=/usr/lib/bjlib2 LDFLAGS="$LDFLAGS"
- make
- make install-strip DESTDIR=$PKG
-cd ..
if [ "$ARCH" = "x86_64" ]; then
mv $PKG/usr/lib $PKG/usr/lib64
- mkdir $PKG/usr/lib64/bjlib2
- install -c -m 644 com/ini/cnnet.ini $PKG/usr/lib64/bjlib2/
- install -c -m 755 com/libs_bin64/libcnnet2.so.* $PKG/usr/lib64/
- install -c -m 755 com/libs_bin64/libcnbpnet20.so.* $PKG/usr/lib64/
- install -c -m 755 com/libs_bin64/libcnbpnet30.so.* $PKG/usr/lib64/
- install -c -m 755 com/libs_bin64/libcnbpcnclapicom2.so.* $PKG/usr/lib64/
-elif [ "$ARCH" = "i686" ]; then
- mkdir $PKG/usr/lib/bjlib2
- install -c -m 644 com/ini/cnnet.ini $PKG/usr/lib/bjlib2/
- install -c -m 755 com/libs_bin32/libcnnet2.so.* $PKG/usr/lib/
- install -c -m 755 com/libs_bin32/libcnbpnet20.so.* $PKG/usr/lib/
- install -c -m 755 com/libs_bin32/libcnbpnet30.so.* $PKG/usr/lib/
- install -c -m 755 com/libs_bin32/libcnbpcnclapicom2.so.* $PKG/usr/lib/
+fi
+mkdir -p $PKG/usr/lib${LIBDIRSUFFIX}/bjlib2
+install -c -o lp -g lp -m 644 com/ini/cnnet.ini $PKG/usr/lib${LIBDIRSUFFIX}/bjlib2/
+install -c -m 755 com/libs_bin${BITS}/*.so.* $PKG/usr/lib${LIBDIRSUFFIX}/
+
+# Run ldconfig in the build script so that /usr/lib{64}/libcn*.so
+# are tracked by doinst.sh
+if [ -x /sbin/ldconfig ]; then
+ /sbin/ldconfig $PKG/usr/lib${LIBDIRSUFFIX}
fi
-mkdir -p $PKG/usr/share/ppd/cnijfilter2
+mkdir -p $PKG/usr/share/ppd/cnijfilter2 $PKG/usr/share/cups/model
cp -a ppd/*.ppd $PKG/usr/share/ppd/cnijfilter2
+PPD_FILES=$( cd $PKG/usr/share/ppd/cnijfilter2 ; ls *.ppd )
+for f in $PPD_FILES; do
+ ln -fs /usr/share/ppd/cnijfilter2/${f} $PKG/usr/share/cups/model/${f}
+done
+
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION/lproptions
cp -a doc/* $PKG/usr/doc/$PRGNAM-$VERSION
cp -a lproptions/lpr* $PKG/usr/doc/$PRGNAM-$VERSION/lproptions
@@ -133,11 +156,11 @@ cat ppd/NEWS > $PKG/usr/doc/$PRGNAM-$VERSION/NEWS
# Copy all README to /usr/doc
for dir in $common_pkg; do
mkdir $PKG/usr/doc/$PRGNAM-$VERSION/$dir
- cd $dir
- for file in AUTHORS COPYING ChangeLog INSTALL LICENSE NEWS README; do
+ pushd $dir
+ for file in AUTHORS COPYING ChangeLog INSTALL LICENSE* NEWS README; do
[ -f $file ] && cp -a $file $PKG/usr/doc/$PRGNAM-$VERSION/$dir
done
- cd ..
+ popd
done
cat $CWD/README > $PKG/usr/doc/$PRGNAM-$VERSION/README.SBo
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
diff --git a/system/cnijfilter2/cnijfilter2.info b/system/cnijfilter2/cnijfilter2.info
index f71f314189..15dabc9821 100644
--- a/system/cnijfilter2/cnijfilter2.info
+++ b/system/cnijfilter2/cnijfilter2.info
@@ -1,8 +1,8 @@
PRGNAM="cnijfilter2"
-VERSION="5.90.1"
-HOMEPAGE="https://asia.canon/en/support/0101048401"
-DOWNLOAD="http://gdlp01.c-wss.com/gds/4/0100010484/01/cnijfilter2-source-5.90-1.tar.gz"
-MD5SUM="11029121b7003a3ebd5d53a1331673a7"
+VERSION="6.10.1"
+HOMEPAGE="https://asia.canon/en/support/0101092101"
+DOWNLOAD="https://gdlp01.c-wss.com/gds/1/0100010921/01/cnijfilter2-source-6.10-1.tar.gz"
+MD5SUM="207715a8b1fd0f727670a87ac46ce46d"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
diff --git a/system/cnijfilter2/gcc10.patch b/system/cnijfilter2/gcc10.patch
new file mode 100644
index 0000000000..0616f6a870
--- /dev/null
+++ b/system/cnijfilter2/gcc10.patch
@@ -0,0 +1,11 @@
+--- cnijfilter2-source-6.10-1.orig/lgmon3/src/cnijlgmon3.c 2020-06-18 14:22:58.000000000 +1200
++++ cnijfilter2-source-6.10-1/lgmon3/src/cnijlgmon3.c 2021-09-06 10:42:18.796063817 +1200
+@@ -55,7 +55,7 @@
+ int (*GET_STATUS)(char *, int, int *, int * , char *);
+ int (*GET_STATUS2)(char *, int, char *, int *, int * , char *, char *);
+ int (*GET_STATUS2_MAINTENANCE)(char *, int, char *, int *, int * , char *, char *);
+-int (*GET_PROTOCOL)(char *, size_t);
++static int (*GET_PROTOCOL)(char *, size_t);
+
+
+ int main(int argc, char *argv[])
diff --git a/system/cnijfilter2/slack-desc b/system/cnijfilter2/slack-desc
index 5d9d84e58f..7b191845ca 100644
--- a/system/cnijfilter2/slack-desc
+++ b/system/cnijfilter2/slack-desc
@@ -16,4 +16,4 @@ cnijfilter2: series, MG2900 series, MB2000 series, MB2300, iB4000 series,
cnijfilter2: MB5000 series, MB5300 series, iP110 series, E450 series, MX490
cnijfilter2: series, E480 series.
cnijfilter2:
-cnijfilter2: Homepage: https://asia.canon/en/support/0101048401
+cnijfilter2: Homepage: https://asia.canon/en/support/0101092101
diff --git a/system/colorize/colorize.SlackBuild b/system/colorize/colorize.SlackBuild
index 5fc7db20ed..a1af6d3fb5 100644
--- a/system/colorize/colorize.SlackBuild
+++ b/system/colorize/colorize.SlackBuild
@@ -22,9 +22,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/conspy/conspy.SlackBuild b/system/conspy/conspy.SlackBuild
index cde6fa5d57..f9234b967b 100644
--- a/system/conspy/conspy.SlackBuild
+++ b/system/conspy/conspy.SlackBuild
@@ -22,9 +22,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/cpmtools/cpmtools.SlackBuild b/system/cpmtools/cpmtools.SlackBuild
index db8bdbe09f..8608da2861 100644
--- a/system/cpmtools/cpmtools.SlackBuild
+++ b/system/cpmtools/cpmtools.SlackBuild
@@ -27,9 +27,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/crc32_simple/crc32_simple.SlackBuild b/system/crc32_simple/crc32_simple.SlackBuild
index 7d27673c84..cd0da9b2fe 100644
--- a/system/crc32_simple/crc32_simple.SlackBuild
+++ b/system/crc32_simple/crc32_simple.SlackBuild
@@ -28,9 +28,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
diff --git a/system/csh/README b/system/csh/README
index 12230bebd9..525cb405ec 100644
--- a/system/csh/README
+++ b/system/csh/README
@@ -1,9 +1,10 @@
csh (C shell from BSD)
-The C shell was originally written at UCB to overcome limitations in the
-Bourne shell. Its flexibility and comfort (at that time) quickly made
-it the shell of choice until more advanced shells like ksh, bash, zsh
-or tcsh appeared. Most of the latter incorporate features original to csh.
+The C shell was originally written at UCB to overcome limitations in
+the Bourne shell. Its flexibility and comfort (at that time) quickly
+made it the shell of choice until more advanced shells like ksh, bash,
+zsh or tcsh appeared. Most of the latter incorporate features original
+to csh.
This build is based on OpenBSD sources from 2011.
diff --git a/system/csh/csh.SlackBuild b/system/csh/csh.SlackBuild
index cf3255cabd..d18ab6e437 100644
--- a/system/csh/csh.SlackBuild
+++ b/system/csh/csh.SlackBuild
@@ -6,6 +6,10 @@
# Licensed under the WTFPL. See http://www.wtfpl.net/txt/copying/ for details.
+# 20210827 bkw:
+# - update to latest debian patch (6), add deb version to VERSION.
+# - add -current fix for recent glibc.
+
# 20170621 bkw:
# - update to latest debian patch (-2.2, needed for -current).
# - quit compiling with -Werror (also needed for -current).
@@ -14,8 +18,8 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=csh
-VERSION=${VERSION:-20110502}
-BUILD=${BUILD:-2}
+VERSION=${VERSION:-20110502_6}
+BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
@@ -27,9 +31,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
@@ -55,11 +56,12 @@ fi
set -e
-DEBVER=2.2
+MAINVER="${VERSION%_*}" # 123_4 => 123
+DEBVER="${VERSION#*_}" # 123_4 => 4
# Grr.
-TARNAM="${PRGNAM}_${VERSION}.orig"
-DIRNAM="${PRGNAM}-${VERSION}.orig"
+TARNAM="${PRGNAM}_${MAINVER}.orig"
+DIRNAM="${PRGNAM}-${MAINVER}.orig"
rm -rf $PKG
mkdir -p $TMP $PKG $OUTPUT
@@ -67,17 +69,14 @@ cd $TMP
rm -rf $DIRNAM
tar xvf $CWD/$TARNAM.tar.gz
cd $DIRNAM
-tar xvf $CWD/${PRGNAM}_${VERSION}-$DEBVER.debian.tar.[xg]z
+tar xvf $CWD/${PRGNAM}_${MAINVER}-$DEBVER.debian.tar.[xg]z
chown -R root:root .
-find -L . \
- \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
- -o -perm 511 \) -exec chmod 755 {} \; -o \
- \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
- -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
+find -L . -perm /111 -a \! -perm 755 -a -exec chmod 755 {} \+ -o \
+ \! -perm /111 -a \! -perm 644 -a -exec chmod 644 {} \+
-# Apply all of Debian's patches.
+# Apply all of Debian's patches. Except one...
for diff in debian/patches/*.diff; do
- patch -p1 < $diff
+ [ "$( basename $diff )" != "09_sys_signame.diff" ] && patch -p1 < $diff
done
# My own patch, keeps csh.h from defining its own (tiny) BUFSIZ. Might
@@ -85,8 +84,15 @@ done
# to set a giant $LS_OPTIONS value without "Word too long" error.
patch -p1 < $CWD/bufsiz.diff
+# 20210827 bkw: my own patch, glibc >= 2.32 no longer exports
+# sys_siglist so we have to use sigdescr_np() instead. Ditto
+# sys_signame and sigabbrev_np(). See glibc changelog:
+# https://sourceware.org/pipermail/libc-announce/2020/000029.html
+# This patch replaces Debian's 09_sys_signame.diff.
+patch -p1 < $CWD/glibc-2.32-sys_siglist.diff
+
# use Slackware standard flags
-sed -i "1iCFLAGS=$SLKCFLAGS" Makefile
+sed -i "1iCFLAGS=$SLKCFLAGS -fcommon" Makefile
# The LIBC= isn't even used, but Slackware64's pmake is broken: it has
# /usr/lib/libc.a hard-coded, and pmake wants to build that (and can't),
diff --git a/system/csh/csh.info b/system/csh/csh.info
index a8ac38100a..527b6dbe26 100644
--- a/system/csh/csh.info
+++ b/system/csh/csh.info
@@ -1,10 +1,10 @@
PRGNAM="csh"
-VERSION="20110502"
+VERSION="20110502_6"
HOMEPAGE="https://packages.debian.org/sid/csh"
-DOWNLOAD="http://ftp.debian.org/debian/pool/main/c/csh/csh_20110502.orig.tar.gz \
- http://http.debian.net/debian/pool/main/c/csh/csh_20110502-2.2.debian.tar.xz"
+DOWNLOAD="https://deb.debian.org/debian/pool/main/c/csh/csh_20110502.orig.tar.gz \
+ https://deb.debian.org/debian/pool/main/c/csh/csh_20110502-6.debian.tar.xz"
MD5SUM="578c40bfa54c09c8affbc434e34fb40c \
- a66e38ff89e978970a4ade6eb419a69a"
+ 22bdcfe61cbbc4f8b8fd69176beadfe7"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES="%README% libbsd"
diff --git a/system/csh/glibc-2.32-sys_siglist.diff b/system/csh/glibc-2.32-sys_siglist.diff
new file mode 100644
index 0000000000..4830e62ae7
--- /dev/null
+++ b/system/csh/glibc-2.32-sys_siglist.diff
@@ -0,0 +1,38 @@
+diff -Naur csh-20110502.orig/proc.c csh-20110502.orig.patched/proc.c
+--- csh-20110502.orig/proc.c 2009-10-27 19:59:21.000000000 -0400
++++ csh-20110502.orig.patched/proc.c 2021-08-27 02:56:08.386981036 -0400
+@@ -726,8 +726,7 @@
+ && (reason != SIGPIPE
+ || (pp->p_flags & PPOU) == 0))) {
+ (void) fprintf(cshout, format,
+- sys_siglist[(unsigned char)
+- pp->p_reason]);
++ sigdescr_np(pp->p_reason));
+ hadnl = 0;
+ }
+ break;
+@@ -948,10 +947,10 @@
+ else if (signum == 0)
+ (void) fputc('0', cshout); /* 0's symbolic name is '0' */
+ else
+- (void) fprintf(cshout, "%s ", sys_signame[signum]);
++ (void) fprintf(cshout, "%s ", sigabbrev_np(signum));
+ } else {
+ for (signum = 1; signum < NSIG; signum++) {
+- (void) fprintf(cshout, "%s ", sys_signame[signum]);
++ (void) fprintf(cshout, "%s ", sigabbrev_np(signum));
+ if (signum == NSIG / 2)
+ (void) fputc('\n', cshout);
+ }
+@@ -978,9 +977,9 @@
+ }
+
+ for (signum = 1; signum < NSIG; signum++)
+- if (!strcasecmp(sys_signame[signum], name) ||
++ if (!strcasecmp(sigabbrev_np(signum), name) ||
+ (strlen(name) > 3 && !strncasecmp("SIG", name, 3) &&
+- !strcasecmp(sys_signame[signum], name + 3)))
++ !strcasecmp(sigabbrev_np(signum), name + 3)))
+ break;
+
+ if (signum == NSIG) {
diff --git a/system/d52/d52.SlackBuild b/system/d52/d52.SlackBuild
index 8657328d5b..8dc201cb80 100644
--- a/system/d52/d52.SlackBuild
+++ b/system/d52/d52.SlackBuild
@@ -22,9 +22,6 @@ if [ -z "$ARCH" ]; then
esac
fi
-# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
-# the name of the created package would be, and then exit. This information
-# could be useful to other scripts.
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
exit 0
@@ -60,11 +57,8 @@ rm -rf $PRGNAM-$VERSION.orig
tar xvf $CWD/${PRGNAM}_$VERSION.orig.tar.gz
cd $PRGNAM-$VERSION.orig
chown -R root:root .
-find -L . \
- \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
- -o -perm 511 \) -exec chmod 755 {} \; -o \
- \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
- -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
+find -L . -perm /111 -a \! -perm 755 -a -exec chmod 755 {} \+ -o \
+ \! -perm /111 -a \! -perm 644 -a -exec chmod 644 {} \+
# Patch from Debian, fix minor security flaw
zcat $CWD/20-fix-format-security-error.patch.gz | patch -p1
diff --git a/system/d52/d52.info b/system/d52/d52.info
index fc92cfb8c9..d1848981ef 100644
--- a/system/d52/d52.info
+++ b/system/d52/d52.info
@@ -1,7 +1,7 @@
PRGNAM="d52"
VERSION="3.4.1"
-HOMEPAGE="http://packages.debian.org/sid/d52"
-DOWNLOAD="http://ftp.debian.org/debian/pool/main/d/d52/d52_3.4.1.orig.tar.gz"
+HOMEPAGE="https://packages.debian.org/sid/d52"
+DOWNLOAD="https://deb.debian.org/debian/pool/main/d/d52/d52_3.4.1.orig.tar.gz"
MD5SUM="0d6fefeb3f30922d1c5046569f2ad665"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
diff --git a/system/dahdi-complete/dahdi-complete.SlackBuild b/system/dahdi-complete/dahdi-complete.SlackBuild
index 4f783a2072..89bcd3ee72 100644
--- a/system/dahdi-complete/dahdi-complete.SlackBuild
+++ b/system/dahdi-complete/dahdi-complete.SlackBuild
@@ -12,7 +12,7 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=dahdi-complete
-VERSION=${VERSION:-3.0.0}
+VERSION=${VERSION:-3.1.0}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
@@ -78,13 +78,15 @@ sed -i -e 's/-Werror //' tools/Makefile.am
sed -i -e 's/sitelib/vendorlib/' linux/build_tools/live_dahdi tools/xpp/Makefile.am
cd linux
+# thanks Gentoo for the patches!
+for i in $CWD/patches/* ; do patch -p1 < $i ; done
make all
cd ../tools
./bootstrap.sh
autoreconf -fi
CPPFLAGS="-I$(pwd)/../linux/include" \
-CFLAGS="$SLKCFLAGS" \
+CFLAGS="$SLKCFLAGS -w -Wl,--allow-multiple-definition" \
CXXFLAGS="$SLKCFLAGS" \
./configure \
--prefix=/usr \
diff --git a/system/dahdi-complete/dahdi-complete.info b/system/dahdi-complete/dahdi-complete.info
index 1c53349c2a..4babd84a54 100644
--- a/system/dahdi-complete/dahdi-complete.info
+++ b/system/dahdi-complete/dahdi-complete.info
@@ -1,8 +1,8 @@
PRGNAM="dahdi-complete"
-VERSION="3.0.0"
+VERSION="3.1.0"
HOMEPAGE="http://www.asterisk.org/downloads/dahdi"
-DOWNLOAD="http://downloads.asterisk.org/pub/telephony/dahdi-linux-complete/releases/dahdi-linux-complete-3.0.0+3.0.0.tar.gz"
-MD5SUM="0e0a7f18bda5f97dcd22369645234231"
+DOWNLOAD="http://downloads.asterisk.org/pub/telephony/dahdi-linux-complete/releases/dahdi-linux-complete-3.1.0+3.1.0.tar.gz"
+MD5SUM="04f04b7986ad5fedd5d5602d55764015"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES=""
diff --git a/system/dahdi-complete/patches/01-no-depmod.patch b/system/dahdi-complete/patches/01-no-depmod.patch
new file mode 100644
index 0000000000..d4286c35ad
--- /dev/null
+++ b/system/dahdi-complete/patches/01-no-depmod.patch
@@ -0,0 +1,12 @@
+diff -uNr dahdi-linux-2.8.0.ORIG//Makefile dahdi-linux-2.8.0/Makefile
+--- dahdi-linux-2.8.0.ORIG//Makefile 2010-09-09 14:41:11.000000000 +0100
++++ dahdi-linux-2.8.0/Makefile 2010-09-09 14:41:27.000000000 +0100
+@@ -139,7 +139,7 @@
+ build_tools/uninstall-modules dahdi $(KVERS)
+ endif
+ $(KMAKE) INSTALL_MOD_PATH=$(DESTDIR) INSTALL_MOD_DIR=dahdi modules_install
+- [ `id -u` = 0 ] && /sbin/depmod -a $(KVERS) || :
++# [ `id -u` = 0 ] && /sbin/depmod -a $(KVERS) || :
+
+ uninstall-modules:
+ ifdef DESTDIR
diff --git a/system/dahdi-complete/patches/02-parallel-make.patch b/system/dahdi-complete/patches/02-parallel-make.patch
new file mode 100644
index 0000000000..946780c266
--- /dev/null
+++ b/system/dahdi-complete/patches/02-parallel-make.patch
@@ -0,0 +1,34 @@
+diff -uNr dahdi-linux-2.8.0.ORIG//Makefile dahdi-linux-2.8.0/Makefile
+--- dahdi-linux-2.8.0/Makefile.ORIG 2013-08-07 13:48:28.909267134 +0100
++++ dahdi-linux-2.8.0/Makefile 2013-08-07 13:50:10.346268656 +0100
+@@ -71,7 +71,7 @@
+ @echo "You do not appear to have the sources for the $(KVERS) kernel installed."
+ @exit 1
+ endif
+- $(KMAKE) modules DAHDI_BUILD_ALL=$(DAHDI_BUILD_ALL)
++ +$(KMAKE) modules DAHDI_BUILD_ALL=$(DAHDI_BUILD_ALL)
+
+ include/dahdi/version.h: FORCE
+ @DAHDIVERSION="${DAHDIVERSION}" build_tools/make_version_h > $@.tmp
+@@ -138,7 +138,7 @@
+ fi
+ build_tools/uninstall-modules dahdi $(KVERS)
+ endif
+- $(KMAKE) INSTALL_MOD_PATH=$(DESTDIR) INSTALL_MOD_DIR=dahdi modules_install
++ +$(KMAKE) INSTALL_MOD_PATH=$(DESTDIR) INSTALL_MOD_DIR=dahdi modules_install
+ # [ `id -u` = 0 ] && /sbin/depmod -a $(KVERS) || :
+
+ uninstall-modules:
+@@ -174,11 +174,11 @@
+
+ clean:
+ ifneq (no,$(HAS_KSRC))
+- $(KMAKE) clean
++ +$(KMAKE) clean
+ endif
+ @rm -f $(GENERATED_DOCS)
+ $(MAKE) -C drivers/dahdi/firmware clean
+ $(MAKE) -C $(KSRC) M='$(PWD)/drivers/dahdi/oct612x' clean
+
+ distclean: dist-clean
+
diff --git a/system/dahdi-complete/patches/04-dahdi-3.1.0-kernel-5.4-support.patch b/system/dahdi-complete/patches/04-dahdi-3.1.0-kernel-5.4-support.patch
new file mode 100644
index 0000000000..e7a2527f06
--- /dev/null
+++ b/system/dahdi-complete/patches/04-dahdi-3.1.0-kernel-5.4-support.patch
@@ -0,0 +1,15 @@
+diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h
+index 22b9b66..eacf6e0 100644
+--- a/include/dahdi/kernel.h
++++ b/include/dahdi/kernel.h
+@@ -59,8 +59,10 @@
+ #include <linux/poll.h>
+
+ #ifdef CONFIG_PCI
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)
+ #include <linux/pci-aspm.h>
+ #endif
++#endif
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+ #define HAVE_NET_DEVICE_OPS
diff --git a/system/dahdi-complete/patches/05-dahdi-3.1.0-r1-div_s64-for-32-bit-arches.patch b/system/dahdi-complete/patches/05-dahdi-3.1.0-r1-div_s64-for-32-bit-arches.patch
new file mode 100644
index 0000000000..f9329edc2b
--- /dev/null
+++ b/system/dahdi-complete/patches/05-dahdi-3.1.0-r1-div_s64-for-32-bit-arches.patch
@@ -0,0 +1,11 @@
+--- dahdi-linux-3.1.0/drivers/dahdi/xpp/xpp_usb.c 2020-03-28 21:34:08.471611500 +0200
++++ dahdi-linux-3.1.0.o/drivers/dahdi/xpp/xpp_usb.c 2020-03-28 21:38:47.169161487 +0200
+@@ -882,7 +882,7 @@
+ usec = 0; /* System clock jumped */
+ if (usec > xusb->max_tx_delay)
+ xusb->max_tx_delay = usec;
+- i = usec / USEC_BUCKET;
++ i = div_s64(usec, USEC_BUCKET);
+ if (i >= NUM_BUCKETS)
+ i = NUM_BUCKETS - 1;
+ xusb->usb_tx_delay[i]++;
diff --git a/system/dahdi-complete/patches/06-non-digium-hardware-and-oslec.patch b/system/dahdi-complete/patches/06-non-digium-hardware-and-oslec.patch
new file mode 100644
index 0000000000..449f67f65c
--- /dev/null
+++ b/system/dahdi-complete/patches/06-non-digium-hardware-and-oslec.patch
@@ -0,0 +1,18351 @@
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/ap400/ap400_drv.c dahdi-extra-dahdi-linux/drivers/dahdi/ap400/ap400_drv.c
+--- dahdi-linux-2.7.0/drivers/dahdi/ap400/ap400_drv.c 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/ap400/ap400_drv.c 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,2341 @@
++/*
++ * AP4XX PCI Card Driver
++ *
++ * Written by Ronaldo Valiati <aligera@aligera.com.br>
++ *
++ * Based on previous works, designs, and architectures conceived and
++ * written by Jim Dixon <jim@lambdatel.com> and Mark Spencer <markster@digium.com>.
++ *
++ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
++ * Copyright (C) 2001-2005, Digium, Inc.
++ *
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/time.h>
++#include <linux/delay.h>
++#include <linux/proc_fs.h>
++#include <dahdi/kernel.h>
++#include <linux/moduleparam.h>
++
++#include "ap400.h"
++
++//#define AP400_DEBUG
++#ifdef AP400_DEBUG
++#define PDEBUG(fmt, args...) { \
++ printk(KERN_DEBUG "AP400 (%d): ",__LINE__); \
++ printk(fmt "\n", ## args); \
++}
++#else
++#define PDEBUG(fmt, args...)
++#endif
++
++/*
++ * Tasklets provide better system interactive response at the cost of the
++ * possibility of losing a frame of data at very infrequent intervals. If
++ * you are more concerned with the performance of your machine, enable the
++ * tasklets. If you are strict about absolutely no drops, then do not enable
++ * tasklets.
++ */
++
++/* #define ENABLE_TASKLETS */
++
++
++/* Work queues are a way to better distribute load on SMP systems */
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
++/*
++ * Work queues can significantly improve performance and scalability
++ * on multi-processor machines, but requires bypassing some kernel
++ * API's, so it's not guaranteed to be compatible with all kernels.
++ */
++/* #define ENABLE_WORKQUEUES */
++#endif
++
++/* Enable HDLC support by hardware */
++#ifdef AP400_HDLC
++#include "ap400_hdlc/ap400_hdlc.c"
++#endif
++
++//#define APEC_SUPPORT
++#ifdef APEC_SUPPORT
++#include "apec.h"
++#endif
++
++/* Workarounds */
++#ifndef IRQF_SHARED
++#define IRQF_SHARED SA_SHIRQ
++#endif
++#ifndef IRQF_DISABLED
++#ifdef SA_INTERRUPT
++#define IRQF_DISABLED SA_INTERRUPT
++#else
++#define IRQF_DISABLED 0x0
++#endif
++#endif
++#ifndef __iomem
++#define __iomem
++#endif
++
++/* Enable prefetching may help performance */
++#define ENABLE_PREFETCH
++
++/* Define to get more attention-grabbing but slightly more I/O using
++ alarm status */
++#define FANCY_ALARM
++
++#define DEBUG_MAIN (1 << 0)
++#define DEBUG_DTMF (1 << 1)
++#define DEBUG_REGS (1 << 2)
++#define DEBUG_TSI (1 << 3)
++#define DEBUG_ECHOCAN (1 << 4)
++#define DEBUG_RBS (1 << 5)
++#define DEBUG_FRAMER (1 << 6)
++
++static int clock_source = -1;
++static int tdm_loop = 0;
++static int apec_enable = 1;
++module_param(tdm_loop, int, 0600);
++module_param(apec_enable, int, 0600);
++
++#ifdef ENABLE_WORKQUEUES
++#include <linux/cpumask.h>
++
++/* XXX UGLY!!!! XXX We have to access the direct structures of the workqueue which
++ are only defined within workqueue.c because they don't give us a routine to allow us
++ to nail a work to a particular thread of the CPU. Nailing to threads gives us substantially
++ higher scalability in multi-CPU environments though! */
++
++/*
++ * The per-CPU workqueue (if single thread, we always use cpu 0's).
++ *
++ * The sequence counters are for flush_scheduled_work(). It wants to wait
++ * until until all currently-scheduled works are completed, but it doesn't
++ * want to be livelocked by new, incoming ones. So it waits until
++ * remove_sequence is >= the insert_sequence which pertained when
++ * flush_scheduled_work() was called.
++ */
++
++struct cpu_workqueue_struct {
++
++ spinlock_t lock;
++
++ long remove_sequence; /* Least-recently added (next to run) */
++ long insert_sequence; /* Next to add */
++
++ struct list_head worklist;
++ wait_queue_head_t more_work;
++ wait_queue_head_t work_done;
++
++ struct workqueue_struct *wq;
++ task_t *thread;
++
++ int run_depth; /* Detect run_workqueue() recursion depth */
++} ____cacheline_aligned;
++
++/*
++ * The externally visible workqueue abstraction is an array of
++ * per-CPU workqueues:
++ */
++struct workqueue_struct {
++ struct cpu_workqueue_struct cpu_wq[NR_CPUS];
++ const char *name;
++ struct list_head list; /* Empty if single thread */
++};
++
++/* Preempt must be disabled. */
++static void __ap4_queue_work(struct cpu_workqueue_struct *cwq,
++ struct work_struct *work)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&cwq->lock, flags);
++ work->wq_data = cwq;
++ list_add_tail(&work->entry, &cwq->worklist);
++ cwq->insert_sequence++;
++ wake_up(&cwq->more_work);
++ spin_unlock_irqrestore(&cwq->lock, flags);
++}
++
++/*
++ * Queue work on a workqueue. Return non-zero if it was successfully
++ * added.
++ *
++ * We queue the work to the CPU it was submitted, but there is no
++ * guarantee that it will be processed by that CPU.
++ */
++static inline int ap4_queue_work(struct workqueue_struct *wq, struct work_struct *work, int cpu)
++{
++ int ret = 0;
++
++ if (!test_and_set_bit(0, &work->pending)) {
++ BUG_ON(!list_empty(&work->entry));
++ __ap4_queue_work(wq->cpu_wq + cpu, work);
++ ret = 1;
++ }
++ return ret;
++}
++
++#endif
++
++static int debug=0;
++static int timingcable;
++static int highestorder;
++static int t1e1override = -1;
++static int j1mode = 0;
++static int loopback = 0;
++static int alarmdebounce = 0;
++
++/* Enabling bursting can more efficiently utilize PCI bus bandwidth, but
++ can also cause PCI bus starvation, especially in combination with other
++ aggressive cards. Please note that burst mode has no effect on CPU
++ utilization / max number of calls / etc. */
++static int noburst = 1;
++static int debugslips = 0;
++static int polling = 0;
++
++#ifdef FANCY_ALARM
++static int altab[] = {
++0, 0, 0, 1, 2, 3, 4, 6, 8, 9, 11, 13, 16, 18, 20, 22, 24, 25, 27, 28, 29, 30, 31, 31, 32, 31, 31, 30, 29, 28, 27, 25, 23, 22, 20, 18, 16, 13, 11, 9, 8, 6, 4, 3, 2, 1, 0, 0,
++};
++#endif
++
++#define FLAG_STARTED (1 << 0)
++#define FLAG_NMF (1 << 1)
++#define FLAG_SENDINGYELLOW (1 << 2)
++
++#define TYPE_T1 1 /* is a T1 card */
++#define TYPE_E1 2 /* is an E1 card */
++#define TYPE_J1 3 /* is a running J1 */
++
++struct devtype {
++ char *desc;
++ unsigned int flags;
++};
++
++static struct devtype ap401 = { "Aligera AP401", 0 };
++static struct devtype ap402 = { "Aligera AP402", 0 };
++static struct devtype ap404 = { "Aligera AP404", 0 };
++static struct devtype ape401 = { "Aligera APE401", 0 };
++static struct devtype ape402 = { "Aligera APE402", 0 };
++static struct devtype ape404 = { "Aligera APE404", 0 };
++
++struct ap4;
++
++struct ap4_span {
++ struct ap4 *owner;
++ unsigned int *writechunk; /* Double-word aligned write memory */
++ unsigned int *readchunk; /* Double-word aligned read memory */
++ int spantype; /* card type, T1 or E1 or J1 */
++ int sync;
++ int psync;
++ int alarmtimer;
++ int redalarms;
++ int notclear;
++ int alarmcount;
++ int spanflags;
++ int syncpos;
++ int e1check; /* E1 check */
++ int reload_cas;
++ unsigned char casbuf[15];
++ unsigned int slipcount;
++ struct dahdi_span span;
++ unsigned char txsigs[16]; /* Transmit sigs */
++ int loopupcnt;
++ int loopdowncnt;
++ unsigned char ec_chunk1[31][DAHDI_CHUNKSIZE]; /* first EC chunk buffer */
++ unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE]; /* second EC chunk buffer */
++ int irqmisses;
++#ifdef ENABLE_WORKQUEUES
++ struct work_struct swork;
++#endif
++ struct dahdi_chan *chans[32]; /* Individual channels */
++};
++
++struct ap4_regs {
++ volatile u32 card_id; // 00h R0
++ volatile u16 fpga_ver; // 04h R1
++ volatile u16 span_num; // 06h R1
++ u32 __unused; // 08h R2
++ volatile u32 liu_config; // 0Ch R3
++ volatile u32 e1_config; // 10h R4
++ volatile u32 e1_status; // 14h R5
++ volatile u32 leds; // 18h R6
++ volatile u32 clock_source; // 1Ch R7
++ u32 __unused3[8]; // 20h - 3Ch R8 - R15
++ volatile u32 echo_ctrl; // 40h R16
++ volatile u32 echo_data; // 44h R17
++ volatile u32 t1_status; // 48h R18
++ volatile u32 t1_config; // 4Ch R19
++};
++
++struct ap4 {
++ /* This structure exists one per card */
++ struct pci_dev *dev; /* Pointer to PCI device */
++ struct dahdi_device *ddev;
++ struct ap4_regs *hw_regs;
++ unsigned int intcount;
++ int flag_1st_irq;
++ int num; /* Which card we are */
++ int fpgaver; /* version of FPGA */
++ int hwid; /* hardware ID */
++ int globalconfig; /* Whether global setup has been done */
++ int syncsrc; /* active sync source */
++ struct ap4_span *tspans[4]; /* Individual spans */
++ int numspans; /* Number of spans on the card */
++ int blinktimer[4];
++#ifdef FANCY_ALARM
++ int alarmpos[4];
++#endif
++ int irq; /* IRQ used by device */
++ int order; /* Order */
++ int flags; /* Device flags */
++ int ledreg; /* LED Register */
++ int e1recover; /* E1 recovery timer */
++ unsigned long memaddr; /* Base address of card */
++ unsigned long memlen;
++ volatile unsigned int *membase; /* Base address of card */
++ int spansstarted; /* number of spans started */
++ /* spinlock_t lock; */ /* lock context */
++ spinlock_t reglock; /* lock register access */
++ volatile unsigned int *writechunk; /* Double-word aligned write memory */
++ volatile unsigned int *readchunk; /* Double-word aligned read memory */
++#ifdef ENABLE_WORKQUEUES
++ atomic_t worklist;
++ struct workqueue_struct *workq;
++#else
++#ifdef ENABLE_TASKLETS
++ int taskletrun;
++ int taskletsched;
++ int taskletpending;
++ int taskletexec;
++ int txerrors;
++ struct tasklet_struct ap4_tlet;
++#endif
++#endif
++ unsigned int passno; /* number of interrupt passes */
++ struct devtype *dt;
++ char *variety;
++ int last0; /* for detecting double-missed IRQ */
++ int checktiming; /* Set >0 to cause the timing source to be checked */
++#ifdef AP400_HDLC
++ struct card_s *hdlc_card;
++#endif
++#ifdef APEC_SUPPORT
++ int apec_enable;
++ struct apec_s *apec;
++#endif
++};
++
++
++static void __set_clear(struct ap4 *wc, int span);
++static int ap4_startup(struct file *file, struct dahdi_span *span);
++static int ap4_shutdown(struct dahdi_span *span);
++static int ap4_rbsbits(struct dahdi_chan *chan, int bits);
++static int ap4_maint(struct dahdi_span *span, int cmd);
++static int ap4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data);
++static void __ap4_set_timing_source(struct ap4 *wc, int unit);
++static void __ap4_check_alarms(struct ap4 *wc, int span);
++static void __ap4_check_sigbits(struct ap4 *wc, int span);
++
++
++#define AP_ACTIVATE (1 << 12)
++
++#define AP_OFF (0)
++#define AP_ON (1)
++
++#define MAX_AP4_CARDS 64
++
++#ifdef ENABLE_TASKLETS
++static void ap4_tasklet(unsigned long data);
++#endif
++
++static struct ap4 *cards[MAX_AP4_CARDS];
++
++//#define ap_debugk(fmt,args...) printk("ap400 -> %s: "fmt, __PRETTY_FUNCTION__, ##args)
++#define ap_debugk(fmt,args...)
++
++//#define TIMER_DEBUG 1
++
++#ifdef TIMER_DEBUG
++struct timer_list ap4xx_opt_timer;
++unsigned int delay = 1000;
++module_param(delay, uint, S_IRUGO);
++#endif
++
++#define PCI_DEVICE_ID_AP4XX 0x1004
++
++static inline void __ap4_set_led(struct ap4 *wc, int span, int color)
++{
++ wc->ledreg &= ~(AP_ON << span);
++ wc->ledreg |= (color << span);
++ *(wc->membase+AP_LEDS_REG) &= ~0x0000000F;
++ *(wc->membase+AP_LEDS_REG) |= ((wc->ledreg)&0x0F);
++}
++
++static inline void ap4_activate(struct ap4 *wc)
++{
++ wc->ledreg |= AP_ACTIVATE;
++}
++
++static void __set_clear(struct ap4 *wc, int span)
++{
++ int i,j;
++ int oldnotclear;
++ unsigned short val=0;
++ struct ap4_span *ts = wc->tspans[span];
++
++ oldnotclear = ts->notclear;
++ if (ts->spantype == TYPE_T1) {
++ for (i=0;i<24;i++) {
++ j = (i/8);
++ if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR) {
++ val |= 1 << (7 - (i % 8));
++ ts->notclear &= ~(1 << i);
++ } else
++ ts->notclear |= (1 << i);
++ if ((i % 8)==7) {
++ val = 0;
++ }
++ }
++ } else {
++ for (i=0;i<31;i++) {
++ if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
++ ts->notclear &= ~(1 << i);
++ else
++ ts->notclear |= (1 << i);
++ }
++ }
++}
++
++#ifdef APEC_SUPPORT
++
++#define APEC_CTRL_RESET 0x80000000
++#define APEC_CTRL_DDR_NCKE 0x40000000
++#define APEC_CTRL_EC_DISABLE 0x20000000
++#define APEC_CTRL_DAS 0x00080000
++#define APEC_CTRL_RD 0x00040000
++#define APEC_CTRL_REQ 0x00020000
++#define APEC_CTRL_READY 0x00010000
++
++#define APEC_ACCESS_TIMEOUT 1000
++
++static inline u16 oct_raw_read (struct ap4_regs *regs, unsigned short addr)
++{
++ unsigned short data;
++ // Poll ready bit
++ while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
++ // Write control bits and address
++ regs->echo_ctrl = APEC_CTRL_RD | APEC_CTRL_REQ | (addr & 0xFFFF);
++ while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
++ data = regs->echo_data & 0xFFFF;
++ //PDEBUG("Raw Read 0x%04hX @ 0x%08X", data, addr);
++ return data;
++}
++
++static inline void oct_raw_write (struct ap4_regs *regs, unsigned short addr,
++ unsigned short data)
++{
++ // Poll ready bit
++ while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
++ // Write data, then control bits and address
++ regs->echo_data = data & 0xFFFF;
++ regs->echo_ctrl = APEC_CTRL_REQ | (addr & 0xFFFF);
++ // Poll ready bit
++ while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
++ //PDEBUG("Raw Write 0x%04hX @ 0x%08X", data, addr);
++ //oct_raw_read(regs, addr);
++}
++
++static inline int oct_ext_wait (struct ap4_regs *regs)
++{
++ int i = APEC_ACCESS_TIMEOUT;
++ while ((oct_raw_read(regs, 0x0) & 0x100) && (i-- > 0));
++ if (i == -1) {
++ printk(KERN_WARNING "Wait access_req timeout\n");
++ return -1;
++ }
++ return 0;
++}
++
++static inline u16 oct_ind_read (struct ap4_regs *regs, unsigned int addr)
++{
++ // Poll access_req bit
++ if (oct_ext_wait(regs))
++ return 0;
++ // Write extended indirect registers
++ oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
++ oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
++ oct_raw_write(regs, 0x0, ((addr & 0xE) << 8) | 0x101);
++ // Poll access_req bit
++ if (oct_ext_wait(regs))
++ return 0;
++ // Return data
++ return oct_raw_read(regs, 0x4);
++}
++
++static inline void oct_ind_write (struct ap4_regs *regs, unsigned int addr,
++ unsigned short data)
++{
++ // Poll access_req bit
++ if (oct_ext_wait(regs))
++ return;
++ oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
++ oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
++ oct_raw_write(regs, 0x4, data);
++ oct_raw_write(regs, 0x0, ((addr & 0xE) << 8) | 0x3101);
++ // Poll access_req bit
++ if (oct_ext_wait(regs))
++ return;
++}
++
++static inline u16 oct_dir_read (struct ap4_regs *regs, unsigned int addr)
++{
++ // Poll access_req bit
++ if (oct_ext_wait(regs))
++ return 0;
++ // Write extended direct registers
++ oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
++ oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
++ oct_raw_write(regs, 0x0, 0x1);
++ regs->echo_ctrl = APEC_CTRL_DAS | APEC_CTRL_RD | APEC_CTRL_REQ | (addr & 0xFFFF);
++ while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
++ // Return data
++ return regs->echo_data;
++}
++
++static inline void oct_dir_write (struct ap4_regs *regs, unsigned int addr,
++ unsigned short data)
++{
++ // Poll access_req bit
++ if (oct_ext_wait(regs))
++ return;
++ // Write extended direct registers
++ oct_raw_write(regs, 0x8, (addr >> 20) & 0x1FFF);
++ oct_raw_write(regs, 0xA, (addr >> 4) & 0xFFFF);
++ oct_raw_write(regs, 0x0, 0x3001);
++ regs->echo_data = data & 0xFFFF;
++ regs->echo_ctrl = APEC_CTRL_DAS | APEC_CTRL_REQ | (addr & 0xFFFF);
++ while ((regs->echo_ctrl & APEC_CTRL_READY) == 0);
++}
++
++
++unsigned int oct_read (void *card, unsigned int addr)
++{
++ struct ap4 *wc = card;
++ int flags;
++ unsigned short data;
++ spin_lock_irqsave(&wc->reglock, flags);
++ data = oct_ind_read(wc->hw_regs, addr);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ PDEBUG("Read 0x%04hX @ 0x%08X", data, addr);
++ return data;
++}
++
++void oct_write (void *card, unsigned int addr, unsigned int data)
++{
++ struct ap4 *wc = card;
++ int flags;
++ spin_lock_irqsave(&wc->reglock, flags);
++ oct_ind_write(wc->hw_regs, addr, data);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ PDEBUG("Write 0x%04hX @ 0x%08X", data, addr);
++}
++
++static int ap4_apec_init(struct ap4 *wc)
++{
++ int laws[4];
++ int i;
++ unsigned int apec_capacity;
++ struct firmware embedded_firmware;
++ const struct firmware *firmware = &embedded_firmware;
++#if !defined(HOTPLUG_FIRMWARE)
++ extern void _binary_OCT6104E_64D_ima_size;
++ extern u8 _binary_OCT6104E_64D_ima_start[];
++ extern void _binary_OCT6104E_128D_ima_size;
++ extern u8 _binary_OCT6104E_128D_ima_start[];
++#else
++ static const char oct64_firmware[] = "OCT6104E-64D.ima";
++ static const char oct128_firmware[] = "OCT6104E-128D.ima";
++#endif
++
++ // Enable DDR and Reset Octasic
++ wc->hw_regs->echo_ctrl |= APEC_CTRL_RESET;
++ wc->hw_regs->echo_ctrl |= APEC_CTRL_DDR_NCKE;
++ udelay(500);
++ wc->hw_regs->echo_ctrl &= APEC_CTRL_RESET;
++ wc->hw_regs->echo_ctrl &= APEC_CTRL_DDR_NCKE;
++ wc->hw_regs->echo_ctrl &= APEC_CTRL_EC_DISABLE;
++
++ /* Setup alaw vs ulaw rules */
++ for (i = 0; i < wc->numspans; i++) {
++ if (wc->tspans[i]->span.channels > 24)
++ laws[i] = 1; // E1: alaw
++ else
++ laws[i] = 0; // T1: ulaw
++ }
++
++ switch ((apec_capacity = apec_capacity_get(wc))) {
++ case 64:
++#if defined(HOTPLUG_FIRMWARE)
++ if ((request_firmware(&firmware, oct64_firmware, &wc->dev->dev) != 0) ||
++ !firmware) {
++ printk("%s: firmware %s not available from userspace\n",
++ wc->variety, oct64_firmware);
++ return -1;
++ }
++#else
++ embedded_firmware.data = _binary_OCT6104E_64D_ima_start;
++ /* Yes... this is weird. objcopy gives us a symbol containing
++ the size of the firmware, not a pointer to a variable containing
++ the size. The only way we can get the value of the symbol
++ is to take its address, so we define it as a pointer and
++ then cast that value to the proper type.
++ */
++ embedded_firmware.size = (size_t) &_binary_OCT6104E_64D_ima_size;
++#endif
++ break;
++ case 128:
++#if defined(HOTPLUG_FIRMWARE)
++ if ((request_firmware(&firmware, oct128_firmware, &wc->dev->dev) != 0) ||
++ !firmware) {
++ printk("%s: firmware %s not available from userspace\n",
++ wc->variety, oct128_firmware);
++ return -1;
++ }
++#else
++ embedded_firmware.data = _binary_OCT6104E_128D_ima_start;
++ /* Yes... this is weird. objcopy gives us a symbol containing
++ the size of the firmware, not a pointer to a variable containing
++ the size. The only way we can get the value of the symbol
++ is to take its address, so we define it as a pointer and
++ then cast that value to the proper type.
++ */
++ embedded_firmware.size = (size_t) &_binary_OCT6104E_128D_ima_size;
++#endif
++ break;
++ default:
++ printk(KERN_INFO "Unsupported channel capacity found on"
++ "echo cancellation module (%d).\n", apec_capacity);
++ return -1;
++ }
++
++ if (!(wc->apec = apec_init(wc, laws, wc->numspans, firmware))) {
++ printk(KERN_WARNING "APEC: Failed to initialize\n");
++ if (firmware != &embedded_firmware)
++ release_firmware(firmware);
++ return -1;
++ }
++
++ if (firmware != &embedded_firmware)
++ release_firmware(firmware);
++
++ printk(KERN_INFO "APEC: Present and operational servicing %d span(s)\n", wc->numspans);
++ return 0;
++}
++
++void ap4_apec_release(struct ap4 *wc)
++{
++ // Disabel DDR and reset Octasic
++ wc->hw_regs->echo_ctrl |= APEC_CTRL_RESET;
++ wc->hw_regs->echo_ctrl |= APEC_CTRL_DDR_NCKE;
++ wc->hw_regs->echo_ctrl |= APEC_CTRL_EC_DISABLE;
++ if (wc->apec)
++ apec_release(wc->apec);
++}
++
++
++static int ap4_echocan(struct dahdi_chan *chan, int eclen)
++{
++ struct ap4 *wc = chan->pvt;
++ int channel;
++
++ if (!wc->apec)
++ return -ENODEV;
++ if (debug)
++ printk(KERN_DEBUG "AP400: ap4_echocan @ Span %d Channel %d Length: %d\n",
++ chan->span->offset, chan->chanpos, eclen);
++ channel = (chan->chanpos << 2) | chan->span->offset;
++ apec_setec(wc->apec, channel, eclen);
++ return 0;
++}
++
++#endif // APEC_SUPPORT
++
++
++static int ap4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
++{
++ struct ap4 *wc = chan->pvt;
++ int span = 0;
++ int alarms = 0;
++ unsigned char c, e1_cfg;
++
++ switch(cmd) {
++ case AP4_GET_ALARMS:
++ if (copy_from_user(&span, (int *)data, sizeof(int)))
++ return -EFAULT;
++ // span starts in zero
++ span--;
++ if (wc->tspans[span]->spantype == TYPE_E1) {
++ /* le status e configuracao do E1 */
++ c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
++ e1_cfg = ((*(wc->membase+AP_E1_CONFIG_REG))>>(8*span));
++ if( c & AP_E1_LOS_STATUS) {
++ alarms = 0x01;
++ } else if( c & AP_E1_AIS_STATUS) {
++ alarms = 0x02;
++ } else if(!(c & AP_E1_BFAE_STATUS)) {
++ alarms = 0x04;
++ if (c & AP_E1_RAI_STATUS)
++ alarms |= 0x08;
++ // Erro de MFA: 00 - MFA desabilitado, 01 - erro de MFA, 10 - MFA OK
++ if ( (c & AP_E1_MFAE_STATUS) && (e1_cfg & AP_E1_CRCEN_CONFIG) )
++ alarms |= 0x10;
++ else if ( (!(c & AP_E1_MFAE_STATUS)) && (e1_cfg & AP_E1_CRCEN_CONFIG) )
++ alarms |= 0x20;
++ // Erro de CAS: 00 - desabilitado, 01 - erro de CAS, 10 - CAS OK
++ if ( (!(c & AP_E1_CAS_STATUS)) && (e1_cfg & AP_E1_PCM30_CONFIG))
++ alarms |= 0x40;
++ else if ( (c & AP_E1_CAS_STATUS) && (e1_cfg & AP_E1_PCM30_CONFIG))
++ alarms |= 0x80;
++ }
++ } else {
++ /* le status e configuracao do E1 */
++ c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
++ if( c & AP_E1_LOS_STATUS)
++ alarms = 0x01;
++ else {
++ c = wc->hw_regs->t1_status >> (8*span);
++ if (!(c & AP4_T1_FRAME_SYNC))
++ alarms = 0x04;
++ }
++ }
++ if(debug) printk("AP4_GET_ALARMS: span = %d, alarms = 0x%02x\n", span+1, alarms);
++ if (copy_to_user((int *)data, &alarms, sizeof(int)))
++ return -EFAULT;
++ break;
++
++ case AP4_GET_SLIPS:
++ if (copy_from_user(&span, (int *)data, sizeof(int)))
++ return -EFAULT;
++ // span starts in zero
++ span--;
++ if((span < wc->numspans) && (span >=0))
++ alarms = wc->tspans[span]->slipcount;
++ if(debug) printk("AP4_GET_SLIPS: span = %d, slips = 0x%02x\n", span+1, alarms);
++ if (copy_to_user((int *)data, &alarms, sizeof(int)))
++ return -EFAULT;
++ break;
++
++ default:
++ PDEBUG("%s: Unknown IOCTL CODE!", wc->variety);
++ return -ENOTTY;
++ }
++ return 0;
++}
++
++static inline struct ap4_span* ap4_span_from_span(struct dahdi_span *span) {
++ return container_of(span, struct ap4_span, span);
++}
++
++static int ap4_maint(struct dahdi_span *span, int cmd)
++{
++ struct ap4_span *ts = ap4_span_from_span(span);
++ struct ap4 *wc = ts->owner;
++
++
++ if (ts->spantype == TYPE_E1) {
++ switch(cmd) {
++ case DAHDI_MAINT_NONE:
++ printk("XXX Turn off local and remote loops E1 XXX\n");
++ *(wc->membase+AP_E1_CONFIG_REG) &= ~(AP_E1_LOOP_CONFIG<<((span->spanno-1)*8));
++ break;
++ case DAHDI_MAINT_LOCALLOOP:
++ printk("XXX Turn on local loopback E1 XXX\n");
++ break;
++ case DAHDI_MAINT_REMOTELOOP:
++ printk("XXX Turn on remote loopback E1 XXX\n");
++ break;
++ case DAHDI_MAINT_LOOPUP:
++ printk("XXX Turn on local loopback on E1 #%d instead of send loopup code XXX\n", span->spanno);
++ *(wc->membase+AP_E1_CONFIG_REG) |= (AP_E1_LOOP_CONFIG<<((span->spanno-1)*8));
++ break;
++ case DAHDI_MAINT_LOOPDOWN:
++ printk("XXX Turn on local loopback on E1 #%d instead of send loopdown code XXX\n", span->spanno);
++ *(wc->membase+AP_E1_CONFIG_REG) |= (AP_E1_LOOP_CONFIG<<((span->spanno-1)*8));
++ break;
++ default:
++ printk("%s: Unknown E1 maint command: %d\n", wc->variety, cmd);
++ break;
++ }
++ } else {
++ switch(cmd) {
++ case DAHDI_MAINT_NONE:
++ printk("XXX Turn off local and remote loops T1 XXX\n");
++ break;
++ case DAHDI_MAINT_LOCALLOOP:
++ printk("XXX Turn on local loop and no remote loop XXX\n");
++ break;
++ case DAHDI_MAINT_REMOTELOOP:
++ printk("XXX Turn on remote loopup XXX\n");
++ break;
++ case DAHDI_MAINT_LOOPUP:
++ break;
++ case DAHDI_MAINT_LOOPDOWN:
++ break;
++ default:
++ printk("%s: Unknown T1 maint command: %d\n", wc->variety, cmd);
++ break;
++ }
++ }
++ return 0;
++}
++
++static int ap4_rbsbits(struct dahdi_chan *chan, int bits)
++{
++ u_char m,c;
++ int k,n,b;
++ struct ap4 *wc = chan->pvt;
++ struct ap4_span *ts = wc->tspans[chan->span->offset];
++ unsigned long flags;
++ volatile unsigned int *writecas = (wc->membase+AP_CAS_BASE);
++ unsigned int allspansbits;
++
++ //ap_debugk("chan->channo = %d, int bits = 0x%08x\n", chan->channo, bits);
++ if(debug & DEBUG_RBS) printk("Setting bits to %d on channel %s\n", bits, chan->name);
++ spin_lock_irqsave(&wc->reglock, flags);
++ k = chan->span->offset;
++ if (ts->spantype == TYPE_E1) { /* do it E1 way */
++ if (chan->chanpos == 16) {
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ return 0;
++ }
++ n = chan->chanpos - 1;
++ if (chan->chanpos > 15) n--;
++ b = (n % 15);
++ c = ts->txsigs[b];
++ m = (n / 15) << 2; /* nibble selector */
++ c &= (0xf << m); /* keep the other nibble */
++ c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
++ ts->txsigs[b] = c;
++ /* monta a word de 32 bits com informacao de todos os spans */
++ allspansbits = wc->tspans[0]->txsigs[b];
++ if (wc->numspans > 1) {
++ allspansbits |= (wc->tspans[1]->txsigs[b] << 8);
++ }
++ if (wc->numspans == 4) {
++ allspansbits |= (wc->tspans[2]->txsigs[b] << 16) |
++ (wc->tspans[3]->txsigs[b] << 24);
++ }
++ /* output them to the chip */
++ writecas[b] = allspansbits;
++ ap_debugk("escrito 0x%08x para ser transmitido pelo CAS (b = %d)\n", allspansbits, b);
++#if 0
++ } else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
++ n = chan->chanpos - 1;
++ b = (n/4);
++ c = ts->txsigs[b];
++ m = ((3 - (n % 4)) << 1); /* nibble selector */
++ c &= ~(0x3 << m); /* keep the other nibble */
++ c |= ((bits >> 2) & 0x3) << m; /* put our new nibble here */
++ ts->txsigs[b] = c;
++ /* output them to the chip */
++ //__ap4_out( ... );
++ } else if (ts->span.lineconfig & DAHDI_CONFIG_ESF) {
++#endif
++ } else {
++ n = chan->chanpos - 1;
++ b = (n/2);
++ c = ts->txsigs[b];
++ m = ((n % 2) << 2); /* nibble selector */
++ c &= (0xf << m); /* keep the other nibble */
++ c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
++ ts->txsigs[b] = c;
++ /* output them to the chip */
++ /* monta a word de 32 bits com informacao de todos os spans */
++ allspansbits = wc->tspans[0]->txsigs[b];
++ if (wc->numspans > 1) {
++ allspansbits |= (wc->tspans[1]->txsigs[b] << 8);
++ }
++ if (wc->numspans == 4) {
++ allspansbits |= (wc->tspans[2]->txsigs[b] << 16) |
++ (wc->tspans[3]->txsigs[b] << 24);
++ }
++ /* output them to the chip */
++ writecas[b] = allspansbits;
++ ap_debugk("escrito 0x%08x para ser transmitido pelo CAS (b = %d)\n", allspansbits, b);
++ }
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ if (debug & DEBUG_RBS)
++ printk("Finished setting RBS bits\n");
++ return 0;
++}
++
++static int ap4_shutdown(struct dahdi_span *span)
++{
++ int tspan;
++ int wasrunning;
++ unsigned long flags;
++ struct ap4_span *ts = ap4_span_from_span(span);
++ struct ap4 *wc = ts->owner;
++
++ tspan = span->offset + 1;
++ if (tspan < 0) {
++ printk("%s: '%d' isn't us?\n", wc->variety, span->spanno);
++ return -1;
++ }
++
++ spin_lock_irqsave(&wc->reglock, flags);
++ wasrunning = span->flags & DAHDI_FLAG_RUNNING;
++
++ span->flags &= ~DAHDI_FLAG_RUNNING;
++ if (wasrunning)
++ wc->spansstarted--;
++ __ap4_set_led(wc, span->offset, AP_OFF);
++ if (((wc->numspans == 4) &&
++ (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)) &&
++ (!(wc->tspans[1]->span.flags & DAHDI_FLAG_RUNNING)) &&
++ (!(wc->tspans[2]->span.flags & DAHDI_FLAG_RUNNING)) &&
++ (!(wc->tspans[3]->span.flags & DAHDI_FLAG_RUNNING)))
++ ||
++ ((wc->numspans == 2) &&
++ (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)) &&
++ (!(wc->tspans[1]->span.flags & DAHDI_FLAG_RUNNING)))
++ ||
++ ((wc->numspans == 1) &&
++ (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)))) {
++ /* No longer in use, disable interrupts */
++ printk("%s: Disabling interrupts since there are no active spans\n",
++ wc->variety);
++ } else wc->checktiming = 1;
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ if (debug & DEBUG_MAIN)
++ printk("Span %d (%s) shutdown\n", span->spanno, span->name);
++ return 0;
++}
++
++static int ap4_spanconfig(struct file *file, struct dahdi_span *span,
++ struct dahdi_lineconfig *lc)
++{
++ int i;
++ struct ap4_span *ts = ap4_span_from_span(span);
++ struct ap4 *wc = ts->owner;
++ unsigned int val;
++
++ printk("About to enter spanconfig!\n");
++ if (debug & DEBUG_MAIN)
++ printk("%s: Configuring span %d\n", wc->variety, span->spanno);
++ /* XXX We assume lineconfig is okay and shouldn't XXX */
++ span->lineconfig = lc->lineconfig;
++ span->txlevel = lc->lbo;
++ span->rxlevel = 0;
++ if (lc->sync < 0)
++ lc->sync = 0;
++ if (lc->sync > 4)
++ lc->sync = 0;
++
++ /* remove this span number from the current sync sources, if there */
++ for(i = 0; i < wc->numspans; i++) {
++ if (wc->tspans[i]->sync == span->spanno) {
++ wc->tspans[i]->sync = 0;
++ wc->tspans[i]->psync = 0;
++ }
++ }
++ wc->tspans[span->offset]->syncpos = lc->sync;
++ /* if a sync src, put it in proper place */
++ if (lc->sync) {
++ wc->tspans[lc->sync - 1]->sync = span->spanno;
++ wc->tspans[lc->sync - 1]->psync = span->offset + 1;
++ }
++ wc->checktiming = 1;
++ /* If we're already running, then go ahead and apply the changes */
++ if (span->flags & DAHDI_FLAG_RUNNING)
++ return ap4_startup(file, span);
++
++ // Limpa contadores de slips, crc e bpv
++ val = (*(wc->membase + AP_CNT_SLIP_REG));
++ val = (*(wc->membase + AP_CNT_CRC_REG));
++ val = (*(wc->membase + AP_CNT_CV_REG));
++
++ ap_debugk("habilitando interrupcao!\n");
++ // Nao considera as primeiras interrupcoes na soma das IRQs perdidas
++ wc->flag_1st_irq = 16;
++ // Enable interrupt
++ *(wc->membase + AP_INT_CONTROL_REG) |= AP_INT_CTL_ENABLE;
++ // Limpa interrupcao da FPGA para forcar borda de subida na proxima
++ val = *(wc->membase + AP_CLEAR_IRQ_REG);
++
++ printk("Done with spanconfig!\n");
++ return 0;
++}
++
++static int ap4_chanconfig(struct file *file, struct dahdi_chan *chan,
++ int sigtype)
++{
++ int alreadyrunning;
++ unsigned long flags;
++ struct ap4 *wc = chan->pvt;
++
++ alreadyrunning = wc->tspans[chan->span->offset]->span.flags & DAHDI_FLAG_RUNNING;
++ if (debug & DEBUG_MAIN) {
++ if (alreadyrunning)
++ printk("%s: Reconfigured channel %d (%s) sigtype %d\n",
++ wc->variety, chan->channo, chan->name, sigtype);
++ else
++ printk("%s: Configured channel %d (%s) sigtype %d\n",
++ wc->variety, chan->channo, chan->name, sigtype);
++ }
++ spin_lock_irqsave(&wc->reglock, flags);
++ if (alreadyrunning)
++ __set_clear(wc, chan->span->offset);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ return 0;
++}
++
++static int ap4_open(struct dahdi_chan *chan)
++{
++ try_module_get(THIS_MODULE);
++ return 0;
++}
++
++static int ap4_close(struct dahdi_chan *chan)
++{
++ module_put(THIS_MODULE);
++ return 0;
++}
++
++static const struct dahdi_span_ops ap4_span_ops = {
++ .owner = THIS_MODULE,
++ .spanconfig = ap4_spanconfig,
++ .chanconfig = ap4_chanconfig,
++ .startup = ap4_startup,
++ .shutdown = ap4_shutdown,
++ .rbsbits = ap4_rbsbits,
++ .maint = ap4_maint,
++ .open = ap4_open,
++ .close = ap4_close,
++#ifdef APEC_SUPPORT
++ .echocan = ap4_echocan,
++#endif
++ .ioctl = ap4_ioctl
++};
++
++static void init_spans(struct ap4 *wc)
++{
++ int x,y;
++ struct ap4_span *ts;
++
++ for (x=0;x<wc->numspans;x++) {
++ ts = wc->tspans[x];
++ sprintf(ts->span.name, "AP4%d%d/%d/%d", 0, wc->numspans, wc->num, x + 1);
++ snprintf(ts->span.desc, sizeof(ts->span.desc) - 1, "AP4%d%d Card %d Span %d", 0, wc->numspans, wc->num+1, x+1);
++ ts->span.ops = &ap4_span_ops;
++ if (ts->spantype == TYPE_E1) {
++ ts->span.channels = 31;
++ ts->span.spantype = SPANTYPE_DIGITAL_E1;
++ ts->span.linecompat = DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
++ ts->span.deflaw = DAHDI_LAW_ALAW;
++ } else {
++ ts->span.channels = 24;
++ ts->span.spantype = SPANTYPE_DIGITAL_T1;
++ ts->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
++ ts->span.deflaw = DAHDI_LAW_MULAW;
++ }
++ ts->span.chans = ts->chans;
++ ts->span.flags = DAHDI_FLAG_RBS;
++ ts->owner = wc;
++ ts->span.offset = x;
++ ts->writechunk = (void *)(wc->writechunk + x * 32 * 2);
++ ts->readchunk = (void *)(wc->readchunk + x * 32 * 2);
++ for (y=0;y<wc->tspans[x]->span.channels;y++) {
++ struct dahdi_chan *mychans = ts->chans[y];
++ sprintf(mychans->name, "AP4%d%d/%d/%d/%d", 0, wc->numspans, wc->num, x + 1, y + 1);
++ mychans->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS |
++ DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_EM_E1 | DAHDI_SIG_DACS_RBS;
++ mychans->pvt = wc;
++ mychans->chanpos = y + 1;
++ }
++ }
++ printk("%s: Spans initialized\n", wc->variety);
++}
++
++
++
++static void __ap4_set_timing_source(struct ap4 *wc, int unit)
++{
++ unsigned int timing;
++ int x;
++
++ if (unit != wc->syncsrc) {
++ if ((unit > -1) && (unit < 4)) {
++ /* define fonte de clock para interface escolhida */
++ timing = *(wc->membase+AP_CLKSRC_REG);
++ timing &= ~AP_CLKSRC_MASK;
++ timing |= unit+1;
++ *(wc->membase+AP_CLKSRC_REG) = timing;
++ } else {
++ /* define clock para interno */
++ timing = *(wc->membase+AP_CLKSRC_REG);
++ timing &= ~AP_CLKSRC_MASK;
++ *(wc->membase+AP_CLKSRC_REG) = timing;
++ }
++ wc->syncsrc = unit;
++ if ((unit < 0) || (unit > 3))
++ unit = 0;
++ else
++ unit++;
++ for (x=0;x<wc->numspans;x++)
++ wc->tspans[x]->span.syncsrc = unit;
++ } else {
++ if (debug & DEBUG_MAIN)
++ printk("%s: Timing source already set to %d\n",
++ wc->variety, unit);
++ }
++ printk("%s: Timing source set to %d (clksrc_reg = 0x%08x)\n",
++ wc->variety, unit, *(wc->membase+AP_CLKSRC_REG));
++}
++
++static void __ap4_set_timing_source_auto(struct ap4 *wc)
++{
++ int x;
++
++ wc->checktiming = 0;
++ for (x=0;x<wc->numspans;x++) {
++ if (wc->tspans[x]->sync) {
++ if ((wc->tspans[wc->tspans[x]->psync - 1]->span.flags & DAHDI_FLAG_RUNNING) &&
++ !(wc->tspans[wc->tspans[x]->psync - 1]->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE) )) {
++ /* Valid timing source */
++ __ap4_set_timing_source(wc, wc->tspans[x]->psync - 1);
++ return;
++ }
++ }
++ }
++ __ap4_set_timing_source(wc, 4);
++}
++
++static void __ap4_configure_t1(struct ap4 *wc, int unit, int lineconfig, int txlevel)
++{
++ char *framing, *line;
++ unsigned int config = 0;
++ unsigned int param = 0;
++ unsigned int linecode = 0;
++
++ wc->tspans[unit]->spantype = TYPE_T1;
++ wc->tspans[unit]->span.channels = 24;
++ wc->tspans[unit]->span.deflaw = DAHDI_LAW_MULAW;
++
++ /* Configure line code */
++ if (unit < 2)
++ linecode = AP_LIU1_LINECODE;
++ else
++ linecode = AP_LIU2_LINECODE;
++ if (lineconfig & DAHDI_CONFIG_AMI) {
++ *(wc->membase+AP_LEDS_REG) |= linecode;
++ line = "AMI";
++ } else {
++ *(wc->membase+AP_LEDS_REG) &= ~linecode;
++ line = "B8ZS";
++ }
++
++ /* loopback test*/
++ //wc->hw_regs->e1_config |= (AP_E1_LOOP_CONFIG << (8 * unit));
++ //printk("E1 config = 0x%08x\n", wc->hw_regs->e1_config);
++
++ /* Configure T1 */
++ config = wc->hw_regs->liu_config;
++ config &= ~(0x000000ff << (8 * unit));
++ config |= (AP_PULS_DSX1_0FT << (8 * unit));
++ wc->hw_regs->liu_config = config;
++
++ param = AP4_T1_NE1_SEL | AP4_T1_CAS_ENABLE;
++ if (lineconfig & DAHDI_CONFIG_D4) {
++ framing = "D4";
++ } else {
++ framing = "ESF";
++ param |= AP4_T1_ESF_NSF;
++ }
++ config = wc->hw_regs->t1_config;
++ config &= ~(0x000000ff << (8 * unit));
++ config |= (param << (8 * unit));
++ wc->hw_regs->t1_config = config;
++
++ printk("T1 Status: 0x%08x\tT1 Config: 0x%08x\tPARAM: 0x%08x\n",
++ wc->hw_regs->t1_status, wc->hw_regs->t1_config, param);
++
++ if (!polling) {
++ __ap4_check_alarms(wc, unit);
++ __ap4_check_sigbits(wc, unit);
++ }
++ printk("%s: Span %d configured for %s/%s\n", wc->variety, unit + 1, framing, line);
++}
++
++static void __ap4_configure_e1(struct ap4 *wc, int unit, int lineconfig)
++{
++ char *crc4 = "";
++ char *framing, *line;
++ unsigned int e1s_cfg, config = 0;
++ unsigned int linecode = 0;
++
++ wc->tspans[unit]->spantype = TYPE_E1;
++ wc->tspans[unit]->span.channels = 31;
++ wc->tspans[unit]->span.deflaw = DAHDI_LAW_ALAW;
++
++ if (loopback) {
++ }
++
++ if (lineconfig & DAHDI_CONFIG_CRC4) {
++ crc4 = "/CRC4";
++ config |= AP_E1_CRCEN_CONFIG;
++ }
++
++ if(unit < 2)
++ linecode = AP_LIU1_LINECODE;
++ else
++ linecode = AP_LIU2_LINECODE;
++ /* Configure line interface */
++ if (lineconfig & DAHDI_CONFIG_AMI) {
++ *(wc->membase+AP_LEDS_REG) |= linecode;
++ line = "AMI";
++ } else {
++ *(wc->membase+AP_LEDS_REG) &= ~linecode;
++ line = "HDB3";
++ }
++
++ if (lineconfig & DAHDI_CONFIG_CCS) {
++ framing = "CCS";
++ } else {
++ framing = "CAS";
++ config |= (AP_E1_CASEN_CONFIG | AP_E1_PCM30_CONFIG);
++ }
++
++ e1s_cfg = *(wc->membase+AP_E1_CONFIG_REG);
++ e1s_cfg &= ~(0x000000ff<<(8*unit));
++ e1s_cfg |= (config<<(8*unit));
++ *(wc->membase+AP_E1_CONFIG_REG) = e1s_cfg;
++
++ /* Disable T1 framer */
++ config = wc->hw_regs->t1_config;
++ config &= ~(0x000000ff << (8 * unit));
++ wc->hw_regs->t1_config = config;
++
++ /* Configure LIU Signalling */
++ e1s_cfg = *(wc->membase+AP_T1E1_CONFIG_REG);
++ e1s_cfg &= ~(0x000000ff<<(8*unit));
++ e1s_cfg |= (AP_PULS_E1_120<<(8*unit));
++ *(wc->membase+AP_T1E1_CONFIG_REG) = e1s_cfg;
++
++ if (!polling) {
++ __ap4_check_alarms(wc, unit);
++ __ap4_check_sigbits(wc, unit);
++ }
++ printk("%s: Span %d configured for %s/%s%s\n",
++ wc->variety, unit + 1, framing, line, crc4);
++}
++
++static int ap4_startup(struct file *file, struct dahdi_span *span)
++{
++ int i;
++ int tspan;
++ unsigned long flags;
++ int alreadyrunning;
++ struct ap4_span *ts = ap4_span_from_span(span);
++ struct ap4 *wc = ts->owner;
++
++ printk("About to enter startup!\n");
++ tspan = span->offset + 1;
++ if (tspan < 0) {
++ printk("%s: Span '%d' isn't us?\n", wc->variety, span->spanno);
++ return -1;
++ }
++
++ spin_lock_irqsave(&wc->reglock, flags);
++
++ alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
++
++ /* initialize the start value for the entire chunk of last ec buffer */
++ for(i = 0; i < span->channels; i++)
++ {
++ memset(ts->ec_chunk1[i],
++ DAHDI_LIN2X(0, span->chans[i]),DAHDI_CHUNKSIZE);
++ memset(ts->ec_chunk2[i],
++ DAHDI_LIN2X(0, span->chans[i]),DAHDI_CHUNKSIZE);
++ }
++
++ /* Force re-evaluation fo timing source */
++// if (timingcable)
++ wc->syncsrc = -1;
++
++ if ((span->lineconfig & DAHDI_CONFIG_D4) || (span->lineconfig & DAHDI_CONFIG_ESF)) {
++ /* is a T1 card */
++ __ap4_configure_t1(wc, span->offset, span->lineconfig, span->txlevel);
++ } else { /* is a E1 card */
++ __ap4_configure_e1(wc, span->offset, span->lineconfig);
++ }
++
++ /* Note clear channel status */
++ wc->tspans[span->offset]->notclear = 0;
++ __set_clear(wc, span->offset);
++
++ if (!alreadyrunning) {
++ span->flags |= DAHDI_FLAG_RUNNING;
++ wc->spansstarted++;
++ /* enable interrupts */
++
++ if (!polling) {
++ __ap4_check_alarms(wc, span->offset);
++ __ap4_check_sigbits(wc, span->offset);
++ }
++ }
++ spin_unlock_irqrestore(&wc->reglock, flags);
++
++ if (wc->tspans[0]->sync == span->spanno) printk("SPAN %d: Primary Sync Source\n",span->spanno);
++ if (wc->numspans > 1) {
++ if (wc->tspans[1]->sync == span->spanno) printk("SPAN %d: Secondary Sync Source\n",span->spanno);
++ }
++ if (wc->numspans == 4) {
++ if (wc->tspans[2]->sync == span->spanno) printk("SPAN %d: Tertiary Sync Source\n",span->spanno);
++ if (wc->tspans[3]->sync == span->spanno) printk("SPAN %d: Quaternary Sync Source\n",span->spanno);
++ }
++
++#ifdef APEC_SUPPORT
++ if (!apec_enable || !wc->apec_enable)
++ wc->hw_regs->echo_ctrl = 0xe0000000;
++ else if (!alreadyrunning && !wc->apec)
++ if (ap4_apec_init(wc))
++ ap4_apec_release(wc);
++#else
++ wc->hw_regs->echo_ctrl = 0xe0000000;
++#endif
++
++ printk("Completed startup!\n");
++ return 0;
++}
++
++
++static void ap4_receiveprep(struct ap4 *wc)
++{
++ volatile unsigned int *readchunk;
++ unsigned int buffer[32];
++ unsigned char *byte = (unsigned char *) buffer;
++ int i, j, k;
++
++ readchunk = (wc->membase + (AP_DATA_BASE));
++ for (i = 0; i < DAHDI_CHUNKSIZE; i++) {
++ /* Prefetch Card data */
++ for (j = 0; j < 32; ++j) {
++ buffer[j] = readchunk[j];
++ }
++ for (j = 0; j < wc->numspans; j++) {
++ /* Set first timeslot for first channel */
++ if (wc->tspans[j]->spantype == TYPE_E1) {
++ for (k = 0; k < 31; ++k) {
++ /* Skip first timeslot from E1 */
++ wc->tspans[j]->span.chans[k]->readchunk[i] =
++ byte[4*(k+1)+j];
++ }
++ }
++ else {
++ for (k = 0; k < 24; ++k) {
++ wc->tspans[j]->span.chans[k]->readchunk[i] =
++ byte[4*k+j];
++ }
++ }
++ }
++ readchunk += 32;
++ }
++
++ for (i = 0; i < wc->numspans; i++) {
++ if (wc->tspans[i]->span.flags & DAHDI_FLAG_RUNNING) {
++ for (j = 0; j < wc->tspans[i]->span.channels; j++) {
++ /* Echo cancel double buffered data */
++ dahdi_ec_chunk(wc->tspans[i]->span.chans[j],
++ wc->tspans[i]->span.chans[j]->readchunk,
++ wc->tspans[i]->ec_chunk2[j]);
++ memcpy(wc->tspans[i]->ec_chunk2[j],wc->tspans[i]->ec_chunk1[j],
++ DAHDI_CHUNKSIZE);
++ memcpy(wc->tspans[i]->ec_chunk1[j],
++ wc->tspans[i]->span.chans[j]->writechunk,
++ DAHDI_CHUNKSIZE);
++ }
++ dahdi_receive(&wc->tspans[i]->span);
++ }
++ }
++}
++
++#if (DAHDI_CHUNKSIZE != 8)
++#error Sorry, AP400 driver does not support chunksize != 8
++#endif
++
++#ifdef ENABLE_WORKQUEUES
++static void workq_handlespan(void *data)
++{
++ struct ap4_span *ts = data;
++ struct ap4 *wc = ts->owner;
++
++// __receive_span(ts);
++// __transmit_span(ts);
++ atomic_dec(&wc->worklist);
++ atomic_read(&wc->worklist);
++
++}
++#endif
++
++static void ap4_transmitprep(struct ap4 *wc)
++{
++ volatile unsigned int *writechunk;
++ int x,y,z;
++ unsigned int tmp;
++
++ for (y=0;y<wc->numspans;y++) {
++ if (wc->tspans[y]->span.flags & DAHDI_FLAG_RUNNING)
++ dahdi_transmit(&wc->tspans[y]->span);
++ }
++
++ writechunk = (wc->membase+(AP_DATA_BASE));
++ for (x=0;x<DAHDI_CHUNKSIZE;x++) {
++ // Once per chunk
++ for (z=0;z<32;z++) {
++ // All channels
++ tmp = 0;
++ for (y = 0; y < wc->numspans; ++y) {
++ if (wc->tspans[y]->spantype == TYPE_T1 && z < 24)
++ tmp |= (wc->tspans[y]->span.chans[z]->writechunk[x]
++ << (8*y));
++ else /* Span Type is E1 */
++ if (z > 0) /* Skip first timeslot */
++ tmp |= (wc->tspans[y]->span.chans[z-1]->writechunk[x]
++ << (8*y));
++ }
++ writechunk[z] = tmp;
++ }
++ // Advance pointer by 4 TDM frame lengths
++ writechunk += 32;
++ }
++
++}
++
++static void ap4_tdm_loop(struct ap4 *wc)
++{
++ volatile unsigned int *buf_ptr;
++ int x,z;
++ unsigned int tmp;
++
++ buf_ptr = (wc->membase+AP_DATA_BASE);
++
++ for (x=0;x<DAHDI_CHUNKSIZE;x++) {
++ // Once per chunk
++ for (z=0;z<32;z++) {
++ tmp = buf_ptr[z];
++ buf_ptr[z] = tmp;
++ }
++ buf_ptr += 32;
++ }
++}
++
++static void __ap4_check_sigbits(struct ap4 *wc, int span)
++{
++ int a,i,rxs;
++ struct ap4_span *ts = wc->tspans[span];
++ volatile unsigned int *readcas = (wc->membase+AP_CAS_BASE);
++
++// if (debug & DEBUG_RBS)
++// printk("Checking sigbits on span %d\n", span + 1);
++
++ if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
++ return;
++ // se span estiver com alarme RED ou BLUE...
++ if( (ts->span.alarms & DAHDI_ALARM_RED) || (ts->span.alarms & DAHDI_ALARM_BLUE) ) {
++ ts->reload_cas = 4;
++ } else if(ts->reload_cas > 0) {
++ // da mais um tempo para framer recuperar e enviar bits de CAS validos
++ ts->reload_cas--;
++ }
++
++ if (ts->spantype == TYPE_E1) {
++ for (i = 0; i < 15; i++) {
++
++ // Se estamos em alarme ou recuperando de um entao mascara os bits para "1101" (bloqueado)
++ if(ts->reload_cas) {
++ a = 0xdd;
++ } else {
++ a = (int) ts->casbuf[i];
++ }
++ ts->casbuf[i] = (unsigned char) (readcas[i] >> (8*span))&0xff;
++
++ /* Get high channel in low bits */
++ rxs = (a & 0xf);
++ if (!(ts->span.chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
++ if (ts->span.chans[i+16]->rxsig != rxs) {
++ ap_debugk("CAS no canal %d mudou de 0x%02x para 0x%02x\n", i+16, ts->span.chans[i+16]->rxsig, rxs);
++ dahdi_rbsbits(ts->span.chans[i+16], rxs);
++ }
++ }
++ rxs = (a >> 4) & 0xf;
++ if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
++ if (ts->span.chans[i]->rxsig != rxs) {
++ ap_debugk("CAS no canal %d mudou de 0x%02x para 0x%02x\n", i, ts->span.chans[i]->rxsig, rxs);
++ dahdi_rbsbits(ts->span.chans[i], rxs);
++ }
++ }
++ }
++ } else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
++ for (i = 0; i < 12; i++) {
++ a = (unsigned char) (readcas[i] >> (8*span)) & 0xcc;
++ rxs = a & 0xc;
++ //rxs = (a & 0xc) >> 2;
++ if (!(ts->span.chans[2*i]->sig & DAHDI_SIG_CLEAR)) {
++ if (ts->span.chans[2*i]->rxsig != rxs)
++ dahdi_rbsbits(ts->span.chans[2*i], rxs);
++ }
++ rxs = (a >> 4) & 0xc;
++ //rxs = ((a >> 4) & 0xc) >> 2;
++ if (!(ts->span.chans[2*i+1]->sig & DAHDI_SIG_CLEAR)) {
++ if (ts->span.chans[2*i+1]->rxsig != rxs)
++ dahdi_rbsbits(ts->span.chans[2*i+1], rxs);
++ }
++ }
++ } else { // ESF
++ for (i = 0; i < 12; i++) {
++ a = (unsigned char) (readcas[i] >> (8*span)) & 0xff;
++ rxs = (a & 0xf);
++ if (!(ts->span.chans[2*i+1]->sig & DAHDI_SIG_CLEAR)) {
++ /* XXX Not really reset on every trans! XXX */
++ if (ts->span.chans[2*i+1]->rxsig != rxs) {
++ dahdi_rbsbits(ts->span.chans[2*i+1], rxs);
++ }
++ }
++ rxs = (a >> 4) & 0xf;
++ if (!(ts->span.chans[2*i]->sig & DAHDI_SIG_CLEAR)) {
++ /* XXX Not really reset on every trans! XXX */
++ if (ts->span.chans[2*i]->rxsig != rxs) {
++ dahdi_rbsbits(ts->span.chans[2*i], rxs);
++ }
++ }
++ }
++ }
++}
++
++static void __ap4_check_alarms(struct ap4 *wc, int span)
++{
++ unsigned char c;
++ int alarms;
++ int x,j;
++ struct ap4_span *ts = wc->tspans[span];
++ unsigned int e1_cfg;
++
++ if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
++ return;
++
++ /* Assume no alarms */
++ alarms = DAHDI_ALARM_NONE;
++
++ /* And consider only carrier alarms */
++ ts->span.alarms &= (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_NOTOPEN);
++
++ if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
++ for (x=0,j=0;x < ts->span.channels;x++)
++ if ((ts->span.chans[x]->flags & DAHDI_FLAG_OPEN)
++#ifdef CONFIG_DAHDI_NET
++ ||
++ (ts->span.chans[x]->flags & DAHDI_FLAG_NETDEV)
++#endif
++ )
++ j++;
++ if (!j)
++ alarms |= DAHDI_ALARM_NOTOPEN;
++ }
++
++/* le status e configuracao do E1 */
++ if (wc->tspans[span]->spantype == TYPE_E1) {
++ c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
++ e1_cfg = ((*(wc->membase+AP_E1_CONFIG_REG))>>(8*span));
++
++ if ((c & AP_E1_LOS_STATUS)||(c & AP_E1_BFAE_STATUS)||(c & AP_E1_AIS_STATUS)) {
++ if (ts->alarmcount >= alarmdebounce)
++ alarms |= DAHDI_ALARM_RED;
++ else
++ ts->alarmcount++;
++ } else
++ ts->alarmcount = 0;
++
++ if ( c & AP_E1_MFAE_STATUS )
++ alarms |= DAHDI_ALARM_BLUE;
++
++ if ( (!(c & AP_E1_CAS_STATUS)) && (e1_cfg & AP_E1_PCM30_CONFIG))
++ alarms |= DAHDI_ALARM_BLUE;
++ } else {
++ c = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*span));
++ if (c & AP_E1_LOS_STATUS) {
++ if (ts->alarmcount >= alarmdebounce)
++ alarms |= DAHDI_ALARM_RED;
++ else
++ ts->alarmcount++;
++ } else
++ ts->alarmcount = 0;
++ c = wc->hw_regs->t1_status >> (8 * span);
++ if (!(c & AP4_T1_FRAME_SYNC))
++ alarms |= DAHDI_ALARM_RED;
++ }
++
++ if (((!ts->span.alarms) && alarms) ||
++ (ts->span.alarms && (!alarms)))
++ wc->checktiming = 1;
++
++ /* Keep track of recovering */
++ if ((!alarms) && ts->span.alarms)
++ ts->alarmtimer = DAHDI_ALARMSETTLE_TIME;
++ if (ts->alarmtimer)
++ alarms |= DAHDI_ALARM_RECOVER;
++
++
++ // If receiving alarms, go into Yellow alarm state
++ if (alarms && !(ts->spanflags & FLAG_SENDINGYELLOW)) {
++ printk("Setting yellow alarm on span %d\n", span + 1);
++ e1_cfg = *(wc->membase+AP_E1_CONFIG_REG);
++ e1_cfg |= (AP_E1_RAI_CONFIG<<(8*span));
++ *(wc->membase+AP_E1_CONFIG_REG) = e1_cfg;
++ ts->spanflags |= FLAG_SENDINGYELLOW;
++ } else if ((!alarms) && (ts->spanflags & FLAG_SENDINGYELLOW)) {
++ printk("Clearing yellow alarm on span %d\n", span + 1);
++ e1_cfg = *(wc->membase+AP_E1_CONFIG_REG);
++ e1_cfg &= ~(AP_E1_RAI_CONFIG<<(8*span));
++ *(wc->membase+AP_E1_CONFIG_REG) = e1_cfg;
++ ts->spanflags &= ~FLAG_SENDINGYELLOW;
++ }
++
++ // Re-check the timing source when we enter/leave alarm, not withstanding yellow alarm
++ if (c & AP_E1_RAI_STATUS)
++ alarms |= DAHDI_ALARM_YELLOW;
++
++ if (ts->span.mainttimer || ts->span.maintstat)
++ alarms |= DAHDI_ALARM_LOOPBACK;
++
++ ts->span.alarms = alarms;
++ dahdi_alarm_notify(&ts->span);
++}
++
++static void __ap4_do_counters(struct ap4 *wc)
++{
++ int span;
++
++ for (span=0;span<wc->numspans;span++) {
++ struct ap4_span *ts = wc->tspans[span];
++ int docheck=0;
++ if (ts->loopupcnt || ts->loopdowncnt)
++ docheck++;
++ if (ts->alarmtimer) {
++ if (!--ts->alarmtimer) {
++ docheck++;
++ ts->span.alarms &= ~(DAHDI_ALARM_RECOVER);
++ }
++ }
++ if (docheck) {
++ if (!polling)
++ __ap4_check_alarms(wc, span);
++ dahdi_alarm_notify(&ts->span);
++ }
++ }
++}
++
++static inline void __handle_leds(struct ap4 *wc)
++{
++ int x, span_status;
++ #define MAX_BLINKTIMER 0x14
++
++ for (x=0;x<wc->numspans;x++) {
++ struct ap4_span *ts = wc->tspans[x];
++ /* le status do E1 (para avaliar LOS) */
++ span_status = ((*(wc->membase+AP_E1_STATUS_REG))>>(8*x));
++ if (ts->span.flags & DAHDI_FLAG_RUNNING) {
++ if(span_status&AP_E1_LOS_STATUS) {
++ if (wc->blinktimer[x] >= (altab[wc->alarmpos[x]] /*>> 1*/)) {
++ __ap4_set_led(wc, x, AP_ON);
++ }
++ if (wc->blinktimer[x] >= (MAX_BLINKTIMER-1)) {
++ __ap4_set_led(wc, x, AP_OFF);
++ }
++ wc->blinktimer[x] += 1;
++ } else if (ts->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE)) {
++ if (wc->blinktimer[x] >= (altab[wc->alarmpos[x]] /*>> 1*/)) {
++ __ap4_set_led(wc, x, AP_ON);
++ }
++ if (wc->blinktimer[x] >= (MAX_BLINKTIMER-2)) {
++ __ap4_set_led(wc, x, AP_OFF);
++ }
++ wc->blinktimer[x] += 3;
++ } /*else if (ts->span.alarms & DAHDI_ALARM_YELLOW) {
++ // Yellow Alarm
++ __ap4_set_led(wc, x, AP_ON);
++ } else if (ts->span.mainttimer || ts->span.maintstat) {
++
++ if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
++ __ap4_set_led(wc, x, AP_GREEN);
++ }
++ if (wc->blinktimer == 0xf) {
++ __ap4_set_led(wc, x, AP_OFF);
++ }
++
++ } */else {
++ /* No Alarm */
++ __ap4_set_led(wc, x, AP_ON);
++ }
++ } else
++ __ap4_set_led(wc, x, AP_OFF);
++
++ if (wc->blinktimer[x] > MAX_BLINKTIMER) {
++ wc->blinktimer[x] = 0;
++ wc->alarmpos[x]++;
++ if (wc->alarmpos[x] >= (sizeof(altab) / sizeof(altab[0])))
++ wc->alarmpos[x] = 0;
++ }
++
++ }
++}
++
++
++static irqreturn_t ap4_interrupt(int irq, void *dev_id)
++{
++ struct ap4 *wc = dev_id;
++ unsigned long flags;
++ int x;
++ static unsigned int val, cfg;
++ unsigned int cnt_irq_misses;
++ static unsigned int cnt_tmp;
++ int ret = 0;
++
++ /* retorna se interrupcao nao foi habilitada ou nao esta ativa */
++ cfg = *(wc->membase + AP_INT_CONTROL_REG);
++ if((cfg & AP_INT_CTL_ENABLE) == 0 || (cfg & AP_INT_CTL_ACTIVE) == 0) {
++ ret = 0;
++ goto out;
++ }
++ /* se chegamos aqui eh porque a interrupcao esta habilitada
++ * e esta ativa, ou seja, foi gerada pelo nosso cartao.
++ * Agora damos o ack da interrupcao */
++ val = *(wc->membase + AP_CLEAR_IRQ_REG);
++
++ /* conta interrupcoes perdidas */
++ if (wc->flag_1st_irq > 0) {
++ // nao considera as primeiras passagens pela rotina
++ cnt_irq_misses = (*(wc->membase+AP_CNT_IRQ_REG));
++ // so considera int. para o cartao
++ if(cnt_irq_misses) {
++ wc->flag_1st_irq--;
++ *(wc->membase+AP_CNT_IRQ_REG)=0;
++ }
++ // zera erro de CRC
++ cnt_tmp = (*(wc->membase + AP_CNT_CRC_REG));
++ } else {
++ // neste registro da FPGA temos o numero de interrupcoes que aconteceram
++ // desde o ultimo reset do contador de interrupcoes. O normal eh ler 1.
++ cnt_irq_misses = (*(wc->membase+AP_CNT_IRQ_REG));
++ // Se for zero significa que a interrupcao nao foi gerada pelo nosso cartao
++ if(cnt_irq_misses == 0) {
++ if(debug) printk("Interrupcao gerada mas nao pela FPGA?!\n");
++ ret = 0;
++ goto out;
++ }
++ // reseta o contador
++ *(wc->membase+AP_CNT_IRQ_REG)=0;
++ for(x=0;x<(wc->numspans);x++)
++ wc->ddev->irqmisses += (cnt_irq_misses-1);
++ }
++
++ if (!wc->spansstarted) {
++ /* Not prepped yet! */
++ ret = 0;
++ goto out;
++ }
++
++ wc->intcount++;
++
++#ifdef ENABLE_WORKQUEUES
++ int cpus = num_online_cpus();
++ atomic_set(&wc->worklist, wc->numspans);
++ if (wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)
++ ap4_queue_work(wc->workq, &wc->tspans[0]->swork, 0);
++ else
++ atomic_dec(&wc->worklist);
++ if (wc->numspans > 1) {
++ if (wc->tspans[1]->span.flags & DAHDI_FLAG_RUNNING)
++ ap4_queue_work(wc->workq, &wc->tspans[1]->swork, 1 % cpus);
++ else
++ atomic_dec(&wc->worklist);
++ }
++ if (wc->numspans == 4) {
++ if (wc->tspans[2]->span.flags & DAHDI_FLAG_RUNNING)
++ ap4_queue_work(wc->workq, &wc->tspans[2]->swork, 2 % cpus);
++ else
++ atomic_dec(&wc->worklist);
++ if (wc->tspans[3]->span.flags & DAHDI_FLAG_RUNNING)
++ ap4_queue_work(wc->workq, &wc->tspans[3]->swork, 3 % cpus);
++ else
++ atomic_dec(&wc->worklist);
++ }
++#else
++ if (tdm_loop == 1)
++ ap4_tdm_loop(wc);
++ else {
++ ap4_receiveprep(wc);
++ ap4_transmitprep(wc);
++ }
++#endif
++
++ // Estatisticas a cada 128ms
++ if(!(wc->intcount&0x7f)){
++ clock_source = wc->hw_regs->clock_source;
++ cnt_tmp = (*(wc->membase + AP_CNT_CV_REG));
++ for(x=0;x<(wc->numspans);x++)
++ wc->tspans[x]->span.count.bpv += (cnt_tmp>>(8*x))&0xff;
++ cnt_tmp = (*(wc->membase + AP_CNT_CRC_REG));
++ for(x=0;x<(wc->numspans);x++)
++ wc->tspans[x]->span.count.crc4 += (cnt_tmp>>(8*x))&0xff;
++ cnt_tmp = (*(wc->membase + AP_CNT_SLIP_REG));
++ for(x=0;x<(wc->numspans);x++) {
++ if (((cnt_tmp>>(8*x))&0xff) && (!(wc->tspans[x]->span.alarms & DAHDI_ALARM_RED)) ){
++ wc->tspans[x]->slipcount++;
++ if(debug) printk("Slip detected on span %d: slipcount = %d\n", x+1, wc->tspans[x]->slipcount);
++ }
++ }
++ }
++
++ spin_lock_irqsave(&wc->reglock, flags);
++
++ __handle_leds(wc);
++
++ __ap4_do_counters(wc);
++
++ //x = wc->intcount & 15;
++ x = wc->intcount & 7;
++ switch(x) {
++ case 0:
++ case 1:
++ case 2:
++ case 3:
++ __ap4_check_alarms(wc, x);
++ break;
++ case 4:
++ case 5:
++ case 6:
++ case 7:
++ __ap4_check_sigbits(wc, x - 4);
++ break;
++ }
++
++ if (wc->checktiming > 0)
++ __ap4_set_timing_source_auto(wc);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ /* IRQ was treated */
++ ret = 1;
++out:
++#ifdef AP400_HDLC
++ /* Call AP400_HDLC_CARD IRQ handler before leave */
++ ret |= ap400_intr_handler(irq, wc->hdlc_card);
++#endif
++
++ return IRQ_RETVAL(ret);
++}
++
++
++static int __devinit ap4_launch(struct ap4 *wc)
++{
++ int x;
++ unsigned long flags;
++
++ if (wc->tspans[0]->span.flags & DAHDI_FLAG_REGISTERED)
++ return 0;
++ printk("%s: Launching card: %d\n", wc->variety, wc->order);
++
++ /* Setup serial parameters and system interface */
++ for (x=0;x<4;x++) {
++ //ap4_serial_setup(wc, x);
++ wc->globalconfig = 1;
++ }
++
++ for (x=0; x<wc->numspans; x++)
++ list_add_tail(&wc->tspans[x]->span.device_node,
++ &wc->ddev->spans);
++ if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
++ printk(KERN_ERR "Unable to register span %s\n", wc->tspans[0]->span.name);
++ return -1; /* FIXME: proper error handling */
++ }
++ wc->checktiming = 1;
++ spin_lock_irqsave(&wc->reglock, flags);
++// __ap4_set_timing_source(wc,4);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++#ifdef ENABLE_TASKLETS
++ tasklet_init(&wc->ap4_tlet, ap4_tasklet, (unsigned long)wc);
++#endif
++ return 0;
++}
++
++
++static int ap4xx_liu_reset(struct ap4 *wc)
++{
++ unsigned int jiffies_hold = jiffies;
++ *(wc->membase+AP_LEDS_REG) |= AP_LIU_RESET_BIT;
++ while(jiffies<=(jiffies_hold+2));
++ *(wc->membase+AP_LEDS_REG) &= ~AP_LIU_RESET_BIT;
++ return 0;
++}
++
++
++static int ap4xx_bus_test(struct ap4 *wc)
++{
++ int tst_result = 0;
++ unsigned int val;
++
++ *(wc->membase+AP_E1_CONFIG_REG) = 0xAAAAAAAA;
++ *wc->membase = 0; // flush
++ val = *(wc->membase+AP_E1_CONFIG_REG);
++ if(val != 0xAAAAAAAA) {
++ printk("Escrito 0xAAAAAAAA, lido 0x%08X!\n", val);
++ tst_result++;
++ }
++ *(wc->membase+AP_E1_CONFIG_REG) = 0x55555555;
++ *wc->membase = 0; // flush
++ val = *(wc->membase+AP_E1_CONFIG_REG);
++ if(val != 0x55555555) {
++ printk("Escrito 0x55555555, lido 0x%08X!\n", val);
++ tst_result++;
++ }
++ *(wc->membase+AP_E1_CONFIG_REG) = 0xFFFFFFFF;
++ *wc->membase = 0; // flush
++ val = *(wc->membase+AP_E1_CONFIG_REG);
++ if(val != 0xFFFFFFFF) {
++ printk("Escrito 0xFFFFFFFF, lido 0x%08X!\n", val);
++ tst_result++;
++ }
++ *(wc->membase+AP_E1_CONFIG_REG) = 0x00000000;
++ *wc->membase = 0xFFFFFFFF; // flush
++ val = *(wc->membase+AP_E1_CONFIG_REG);
++ if(val != 0x00000000) {
++ printk("Escrito 0x00000000, lido 0x%08X!\n", val);
++ tst_result++;
++ }
++ return tst_result;
++}
++
++#ifdef TIMER_DEBUG
++void ap4xx_opt_timeout(unsigned long arg)
++{
++ struct pci_dev *dev = (struct pci_dev *)arg;
++ struct ap4 *wc = pci_get_drvdata(dev);
++
++// ap_debugk("wc->tspans[0]->span.chans[1].readchunk[1] = 0x%02x\n", wc->tspans[0]->span.chans[0].readchunk[1]);
++// ap_debugk("e1s_cfg = 0x%08x\n", *(wc->membase+AP_E1_CONFIG_REG));
++// ap_debugk("e1_status = 0x%08x\n", *(wc->membase + AP_E1_STATUS_REG));
++// ap_debugk("clk_cfg = 0x%08x\n", *(wc->membase+0x07));
++// ap_debugk("e1_data = 0x%08x\n", *(wc->membase + (AP_DATA_BASE + 1)));
++// ap_debugk("cas_data = 0x%08x\n", *(wc->membase + AP_CAS_BASE));
++
++ // dispara timer novamente
++ init_timer(&ap4xx_opt_timer);
++ ap4xx_opt_timer.function = ap4xx_opt_timeout;
++ ap4xx_opt_timer.data = arg;
++ ap4xx_opt_timer.expires = jiffies + (delay/4);
++ add_timer(&ap4xx_opt_timer);
++
++}
++#endif
++
++static inline int ap4_card_detect (struct ap4 *wc) {
++ int i;
++ if ((wc->hw_regs->card_id != AP4XX_CARD_ID) &&
++ (wc->hw_regs->card_id != APE4XX_CARD_ID)) {
++ printk("AP400: Unknown card ID(0x%08X)! Aborting...\n", wc->hw_regs->card_id);
++ return -EPERM;
++ }
++ // Test bus integrity
++ for (i=0; i < 1000; i++) {
++ if (ap4xx_bus_test(wc)) {
++ printk("AP400: Bus integrity test failed! Aborting...\n");
++ return -EIO;
++ }
++ }
++ printk("AP400: Bus integrity OK!\n");
++
++ wc->fpgaver = wc->hw_regs->fpga_ver;
++ wc->numspans = wc->hw_regs->span_num;
++ wc->hwid = ((*(wc->membase+AP_HWCONFIG_REG))&AP_HWID_MASK)>>4;
++
++ if ((wc->hwid == AP_HWID_1E1_RJ && wc->numspans != 1) ||
++ (wc->hwid == AP_HWID_2E1_RJ && wc->numspans != 2) ||
++ (wc->hwid == AP_HWID_4E1_RJ && wc->numspans != 4)) {
++ printk("AP400: Incompatible Hardware ID(0x%02x)! Aborting...\n", wc->hwid);
++ return -EIO;
++ }
++
++ if (wc->hw_regs->card_id == AP4XX_CARD_ID)
++ switch (wc->numspans) {
++ case 1:
++ wc->dt = (struct devtype *) &ap401;
++ break;
++ case 2:
++ wc->dt = (struct devtype *) &ap402;
++ break;
++ case 4:
++ wc->dt = (struct devtype *) &ap404;
++ break;
++ default:
++ printk("AP400: Unsupported spans number(%d)! Aborting...\n",
++ wc->numspans);
++ return -EPERM;
++ }
++ else
++ switch (wc->numspans) {
++ case 1:
++ wc->dt = (struct devtype *) &ape401;
++ break;
++ case 2:
++ wc->dt = (struct devtype *) &ape402;
++ break;
++ case 4:
++ wc->dt = (struct devtype *) &ape404;
++ break;
++ default:
++ printk("APE400: Unsupported spans number(%d)! Aborting...\n",
++ wc->numspans);
++ return -EPERM;
++ }
++
++ wc->variety = wc->dt->desc;
++ printk("Found a %s (firmware version %d.%d) at base address %08lx, remapped to %p\n",
++ wc->variety, wc->fpgaver >> 8, wc->fpgaver & 0xFF,
++ wc->memaddr, wc->membase);
++
++ return 0;
++}
++
++static void __devexit ap4_remove_one(struct pci_dev *pdev);
++
++static int __devinit ap4_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
++{
++ int res;
++ struct ap4 *wc;
++ int x,f;
++ int basesize;
++ static int initd_ifaces=0;
++ // Initialize pointer struct
++ if(!initd_ifaces){
++ memset((void *)cards,0,(sizeof(struct ap4 *))*MAX_AP4_CARDS);
++ initd_ifaces=1;
++ }
++
++ if ((res = pci_enable_device(pdev)) != 0) {
++ goto out;
++ }
++ // Allocate card struct
++ wc = kmalloc(sizeof(struct ap4), GFP_KERNEL);
++ if (wc == NULL) {
++ res = -ENOMEM;
++ goto out;
++ }
++
++ memset(wc, 0x0, sizeof(struct ap4));
++ spin_lock_init(&wc->reglock);
++
++ basesize = DAHDI_MAX_CHUNKSIZE * 32 * 2 * 4;
++
++ // Request PCI regions
++ if ((res = pci_request_regions(pdev, "ap400")) != 0) {
++ printk("AP400: Unable to request regions!\n");
++ goto out;
++ }
++
++ // Remap PCI address
++ wc->memaddr = pci_resource_start(pdev, 2);
++ wc->memlen = pci_resource_len(pdev, 2);
++ wc->membase = ioremap(wc->memaddr, wc->memlen);
++ if(wc->membase == NULL) {
++ printk("AP400: ioremap failed!\n");
++ res = -EIO;
++ goto out;
++ }
++ wc->hw_regs = (struct ap4_regs *) wc->membase;
++
++ // Detect Card model
++ if ((res = ap4_card_detect(wc)) != 0)
++ goto out;
++
++ ap4xx_liu_reset(wc);
++
++ // This rids of the Double missed interrupt message after loading
++ wc->last0 = 1;
++
++ wc->dev = pdev;
++
++ // 32 channels, Double-buffer, Read/Write, 4 spans
++ wc->writechunk = kmalloc(basesize * 2, GFP_KERNEL);
++ if (!wc->writechunk) {
++ printk("%s: Unable to allocate memory!\n", wc->variety);
++ res = -ENOMEM;
++ goto out;
++ }
++
++ // Read is after the whole write piece (in words)
++ wc->readchunk = wc->writechunk + basesize / 4;
++
++
++ // Initialize Write/Buffers to all blank data
++ memset((void *) wc->writechunk, 0x00, basesize);
++ memset((void *) wc->readchunk, 0xff, basesize);
++
++ /* Keep track of which device we are */
++ pci_set_drvdata(pdev, wc);
++
++ /* inicializa contador de interrupcao */
++ wc->intcount = 0;
++
++ for(x = 0; x < MAX_AP4_CARDS; x++) {
++ if (!cards[x]) break;
++ }
++
++ if (x >= MAX_AP4_CARDS) {
++ printk("No cards[] slot available!!\n");
++ res = -ENOMEM;
++ goto out;
++ }
++
++ wc->num = x;
++ cards[x] = wc;
++
++ /* Allocate pieces we need here, consider 31 channels for E1*/
++ for (x=0;x<4;x++) {
++ wc->tspans[x] = kmalloc(sizeof(struct ap4_span), GFP_KERNEL);
++ if (wc->tspans[x]) {
++ memset(wc->tspans[x], 0, sizeof(struct ap4_span));
++ wc->tspans[x]->spantype = TYPE_E1;
++ } else {
++ res = -ENOMEM;
++ goto out;
++ }
++ for (f = 0; f < 31; f++) {
++ if (!(wc->tspans[x]->chans[f] = kmalloc(sizeof(*wc->tspans[x]->chans[f]), GFP_KERNEL))) {
++ res = -ENOMEM;
++ goto out;
++ }
++ memset(wc->tspans[x]->chans[f], 0, sizeof(*wc->tspans[x]->chans[f]));
++ }
++#ifdef ENABLE_WORKQUEUES
++ INIT_WORK(&wc->tspans[x]->swork, workq_handlespan, wc->tspans[x]);
++#endif
++ wc->tspans[x]->spanflags |= wc->dt->flags;
++ }
++
++ if (request_irq(pdev->irq, ap4_interrupt, IRQF_DISABLED | IRQF_SHARED, "ap400", wc))
++ {
++ printk("%s: Unable to request IRQ %d\n", wc->variety, pdev->irq);
++ res = -EIO;
++ goto out;
++ }
++
++ wc->ddev = dahdi_create_device();
++ wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
++ wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
++ if (!wc->ddev->location)
++ return -ENOMEM; /* FIXME: proper error handling */
++ wc->ddev->manufacturer = "Aligera";
++ wc->ddev->devicetype = wc->variety;
++ wc->ddev->irqmisses = 0;
++ init_spans(wc);
++
++ /* Launch cards as appropriate */
++ x = 0;
++ for(;;) {
++ /* Find a card to activate */
++ f = 0;
++ for (x=0;cards[x];x++) {
++ if (cards[x]->order <= highestorder) {
++ ap4_launch(cards[x]);
++ if (cards[x]->order == highestorder)
++ f = 1;
++ }
++ }
++ /* If we found at least one, increment the highest order and search again, otherwise stop */
++ if (f)
++ highestorder++;
++ else
++ break;
++ }
++
++#ifdef APEC_SUPPORT
++ if (wc->fpgaver >= 0x0400)
++ wc->apec_enable = 1;
++#endif
++
++#ifdef TIMER_DEBUG
++ // dispara timer de debug
++ init_timer(&ap4xx_opt_timer);
++ ap4xx_opt_timer.function = ap4xx_opt_timeout;
++ ap4xx_opt_timer.data = (unsigned long) pdev;
++ ap4xx_opt_timer.expires = jiffies + 100;
++ add_timer(&ap4xx_opt_timer);
++#endif
++
++ /* Initialize HDLC_CARD */
++#ifdef AP400_HDLC
++ u8 __iomem *base_addr[3];
++ unsigned int bar_size[3];
++ int i;
++ base_addr[2] = (void *) wc->membase;
++ bar_size[2] = wc->memlen;
++ for (i = 0; i < 2; i++) {
++ bar_size[i] = (u32) pci_resource_len(pdev, i);
++ base_addr[i] = ioremap(pci_resource_start(pdev, i),
++ bar_size[i]);
++ if (base_addr[i] == NULL) {
++ printk(KERN_ERR "Memory map failed\n");
++ res = -ENODEV;
++ goto out;
++ }
++ }
++ ap400_card_init(&wc->hdlc_card, base_addr, bar_size);
++ ap400_intr_enable(wc->hdlc_card);
++#endif
++
++ res = 0;
++out:
++ if (res != 0) {
++ ap4_remove_one(pdev);
++ }
++ return res;
++}
++
++static void __devexit ap4_remove_one(struct pci_dev *pdev)
++{
++ struct ap4 *wc = pci_get_drvdata(pdev);
++ int x;
++
++ if (wc) {
++ ap_debugk("desabilita interrupcao!\n");
++ // desabilita interrupcao
++ *(wc->membase + AP_INT_CONTROL_REG) &= ~AP_INT_CTL_ENABLE;
++
++#ifdef APEC_SUPPORT
++ // Stop echo cancellation module
++ ap4_apec_release(wc);
++#endif
++ /* Unregister spans */
++ dahdi_unregister_device(wc->ddev);
++ kfree(wc->ddev->location);
++ dahdi_free_device(wc->ddev);
++#ifdef ENABLE_WORKQUEUES
++ if (wc->workq) {
++ flush_workqueue(wc->workq);
++ destroy_workqueue(wc->workq);
++ }
++#endif
++
++#ifdef TIMER_DEBUG
++ del_timer(&ap4xx_opt_timer);
++#endif
++
++ wc->hw_regs = NULL;
++ if(wc->membase)
++ iounmap((void *)wc->membase);
++
++ /* Immediately free resources */
++ kfree((void *) wc->writechunk);
++
++#ifdef AP400_HDLC
++ /* Remove HDLC Card */
++ ap400_card_remove(wc->hdlc_card);
++ if (wc->hdlc_card->cfg_base_addr)
++ iounmap(wc->hdlc_card->cfg_base_addr);
++ if (wc->hdlc_card->buf_base_addr)
++ iounmap(wc->hdlc_card->buf_base_addr);
++ kfree(wc->hdlc_card);
++#endif
++ free_irq(pdev->irq, wc);
++
++ cards[wc->num] = NULL;
++ for (x=0;x<wc->numspans;x++) {
++ if (wc->tspans[x])
++ kfree(wc->tspans[x]);
++ }
++ kfree(wc);
++ }
++ pci_release_regions(pdev);
++ pci_disable_device(pdev);
++ pci_set_drvdata(pdev, NULL);
++ printk(KERN_INFO "AP400 driver removed\n");
++}
++
++
++static struct pci_device_id ap4_pci_tbl[] __devinitdata =
++{
++ { PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_AP4XX), },
++ { 0, }
++};
++
++
++static struct pci_driver ap4_driver = {
++ .name = "Unified ap4xx driver",
++ .probe = ap4_init_one,
++#ifdef LINUX26
++ .remove = __devexit_p(ap4_remove_one),
++#else
++ .remove = ap4_remove_one,
++#endif
++ .id_table = ap4_pci_tbl,
++};
++
++static int __init ap4_init(void)
++{
++ int res;
++ printk("Unified AP4XX PCI Card Driver\n");
++ res = pci_register_driver(&ap4_driver);
++ if (res) {
++ return -ENODEV;
++ }
++ return 0;
++}
++
++static void __exit ap4_cleanup(void)
++{
++ printk("Unified AP4XX PCI Card Driver Cleanup\n");
++ pci_unregister_driver(&ap4_driver);
++}
++
++
++MODULE_AUTHOR("Aligera (aligera@aligera.com.br)");
++MODULE_DESCRIPTION("Unified AP4XX PCI Card Driver");
++#ifdef MODULE_LICENSE
++MODULE_LICENSE("GPL");
++#endif
++module_param(debug, int, 0600);
++module_param(loopback, int, 0600);
++module_param(noburst, int, 0600);
++module_param(debugslips, int, 0600);
++module_param(polling, int, 0600);
++module_param(timingcable, int, 0600);
++module_param(t1e1override, int, 0600);
++module_param(alarmdebounce, int, 0600);
++module_param(j1mode, int, 0600);
++
++MODULE_DEVICE_TABLE(pci, ap4_pci_tbl);
++
++module_init(ap4_init);
++module_exit(ap4_cleanup);
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/ap400/ap400.h dahdi-extra-dahdi-linux/drivers/dahdi/ap400/ap400.h
+--- dahdi-linux-2.7.0/drivers/dahdi/ap400/ap400.h 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/ap400/ap400.h 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,107 @@
++/*
++ * AP4XX T1/E1 PCI Driver
++ *
++ * Written by Ronaldo Valiati <aligera@aligera.com.br>
++ *
++ * Based on previous works, designs, and archetectures conceived and
++ * written by Jim Dixon <jim@lambdatel.com> and Mark Spencer <markster@digium.com>.
++ *
++ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
++ * Copyright (C) 2001-2005, Digium, Inc.
++ *
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#include <linux/ioctl.h>
++
++
++#define AP4_GET_ALARMS _IOW (DAHDI_CODE, 60, int)
++#define AP4_GET_SLIPS _IOW (DAHDI_CODE, 61, int)
++
++#define AP4XX_CARD_ID 0x41434532 // "ACE2"
++#define APE4XX_CARD_ID 0x41504534 // "APE4"
++
++#define AP_CAS_BASE 0x0080
++#define AP_DATA_BASE 0x0100
++
++#define AP_CARD_TYPE_REG 0x0001
++#define AP_T1E1_CONFIG_REG 0x0003
++#define AP_E1_CONFIG_REG 0x0004
++#define AP_E1_STATUS_REG 0x0005
++#define AP_LEDS_REG 0x0006
++#define AP_CLKSRC_REG 0x0007
++#define AP_HWCONFIG_REG 0x0008
++#define AP_INT_CONTROL_REG 0x0009
++#define AP_CNT_IRQ_REG 0x000B
++#define AP_CNT_CV_REG 0x000C
++#define AP_CNT_CRC_REG 0x000D
++#define AP_CLEAR_IRQ_REG 0x000E
++#define AP_CNT_SLIP_REG 0x000F
++
++#define AP_HWID_MASK 0x00F0
++
++#define AP_CLKSRC_MASK 0x07
++
++#define AP_LIU1_LINECODE 0x0080
++#define AP_LIU2_LINECODE 0x0100
++#define AP_LIU_RESET_BIT 0x0200
++
++#define AP_E1_AIS_STATUS 0x01
++#define AP_E1_BFAE_STATUS 0x02
++#define AP_E1_MFAE_STATUS 0x04
++#define AP_E1_SYNC_STATUS 0x08
++#define AP_E1_CAS_STATUS 0x10
++#define AP_E1_LOS_STATUS 0x20
++#define AP_E1_RAI_STATUS 0x40
++
++#define AP_E1_RAI_CONFIG 0x01
++#define AP_E1_LOOP_CONFIG 0x10
++#define AP_E1_CASEN_CONFIG 0x20
++#define AP_E1_PCM30_CONFIG 0x40
++#define AP_E1_CRCEN_CONFIG 0x80
++
++#define AP_INT_CTL_ENABLE 0x01
++#define AP_INT_CTL_ACTIVE 0x02
++
++#define AP_HWID_1E1_RJ 0x01
++#define AP_HWID_2E1_RJ 0x00
++#define AP_HWID_4E1_RJ 0x02
++#define AP_HWID_T1 0x04
++
++#define AP4_T1_NE1_SEL 0x04
++#define AP4_T1_ESF_NSF 0x02
++#define AP4_T1_CAS_ENABLE 0x01
++
++#define AP4_T1_FRAME_SYNC 0x01
++
++
++typedef enum {
++ AP_PULS_E1_75 = 0,
++ AP_PULS_E1_120,
++ AP_PULS_DSX1_0FT,
++ AP_PULS_DSX1_133FT,
++ AP_PULS_DSX1_266FT,
++ AP_PULS_DSX1_399FT,
++ AP_PULS_DSX1_533FT,
++ AP_PULS_J1_110,
++ AP_PULS_DS1_0DB,
++ AP_PULS_DS1_M075DB,
++ AP_PULS_DS1_M150DB,
++ AP_PULS_DS1_M225DB
++} liu_mode;
++
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/ap400/apec.c dahdi-extra-dahdi-linux/drivers/dahdi/ap400/apec.c
+--- dahdi-linux-2.7.0/drivers/dahdi/ap400/apec.c 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/ap400/apec.c 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,400 @@
++/*
++ * AP400 Echo Cancelation Hardware support
++ *
++ * Written by Wagner Gegler <aligera@aligera.com.br>
++ *
++ * Based on previous work written by Mark Spencer <markster@digium.com>
++ *
++ * Copyright (C) 2005-2006 Digium, Inc.
++ *
++ * Mark Spencer <markster@digium.com>
++ *
++ * All Rights Reserved
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/string.h>
++#include <linux/time.h>
++#include <linux/version.h>
++#include <linux/delay.h>
++
++#include "apec.h"
++#include "oct6100api/oct6100_api.h"
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
++#include <linux/config.h>
++#else
++#include <linux/autoconf.h>
++#endif
++
++/* API for Octasic access */
++UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
++{
++ /* Why couldn't they just take a timeval like everyone else? */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
++ struct timeval tv;
++#else
++ struct timespec64 tv;
++#endif
++ unsigned long long total_usecs;
++ unsigned int mask = ~0;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
++ do_gettimeofday(&tv);
++ total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
++ (((unsigned long long)(tv.tv_usec)));
++#else
++ ktime_get_real_ts64(&tv);
++ total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
++ (((unsigned long long)(tv.tv_nsec))) / 1000;
++#endif
++ f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
++ f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength)
++{
++ memset(f_pAddress, f_ulPattern, f_ulLength);
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength)
++{
++ memcpy(f_pDestination, f_pSource, f_ulLength);
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
++{
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
++{
++#ifdef OCTASIC_DEBUG
++ printk("I should never be called! (destroy serialize object)\n");
++#endif
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
++{
++ /* Not needed */
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
++{
++ /* Not needed */
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
++{
++ oct_write(f_pWriteParams->pProcessContext, f_pWriteParams->ulWriteAddress, f_pWriteParams->usWriteData);
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
++{
++ unsigned int x;
++ for (x=0;x<f_pSmearParams->ulWriteLength;x++) {
++ oct_write(f_pSmearParams->pProcessContext, f_pSmearParams->ulWriteAddress + (x << 1), f_pSmearParams->usWriteData);
++ }
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
++{
++ unsigned int x;
++ for (x=0;x<f_pBurstParams->ulWriteLength;x++) {
++ oct_write(f_pBurstParams->pProcessContext, f_pBurstParams->ulWriteAddress + (x << 1), f_pBurstParams->pusWriteData[x]);
++ }
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
++{
++ *(f_pReadParams->pusReadData) = oct_read(f_pReadParams->pProcessContext, f_pReadParams->ulReadAddress);
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
++{
++ unsigned int x;
++ for (x=0;x<f_pBurstParams->ulReadLength;x++) {
++ f_pBurstParams->pusReadData[x] = oct_read(f_pBurstParams->pProcessContext, f_pBurstParams->ulReadAddress + (x << 1));
++ }
++ return cOCT6100_ERR_OK;
++}
++
++#if 0
++#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_HT_FREEZE
++#else
++#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_POWER_DOWN
++#endif
++
++struct apec_s {
++ tPOCT6100_INSTANCE_API pApiInstance;
++ UINT32 aulEchoChanHndl[128];
++ int chanflags[128];
++ int ecmode[128];
++ int numchans;
++};
++
++#define FLAG_DTMF (1 << 0)
++#define FLAG_MUTE (1 << 1)
++#define FLAG_ECHO (1 << 2)
++
++static void apec_setecmode(struct apec_s *apec, int channel, int mode)
++{
++ tOCT6100_CHANNEL_MODIFY *modify;
++ UINT32 ulResult;
++
++ if (apec->ecmode[channel] == mode)
++ return;
++ modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_ATOMIC);
++ if (!modify) {
++ printk("APEC: Unable to allocate memory for setec!\n");
++ return;
++ }
++ Oct6100ChannelModifyDef(modify);
++ modify->ulEchoOperationMode = mode;
++ modify->ulChannelHndl = apec->aulEchoChanHndl[channel];
++ ulResult = Oct6100ChannelModify(apec->pApiInstance, modify);
++ if (ulResult != GENERIC_OK) {
++ printk("Failed to apply echo can changes on channel %d!\n", channel);
++ } else {
++#ifdef OCTASIC_DEBUG
++ printk("Echo can on channel %d set to %d\n", channel, mode);
++#endif
++ apec->ecmode[channel] = mode;
++ }
++ kfree(modify);
++}
++
++void apec_setec(struct apec_s *apec, int channel, int eclen)
++{
++ if (eclen) {
++ apec->chanflags[channel] |= FLAG_ECHO;
++ apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
++ apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_NORMAL);
++ } else {
++ apec->chanflags[channel] &= ~FLAG_ECHO;
++ if (apec->chanflags[channel] & (FLAG_DTMF | FLAG_MUTE)) {
++ apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
++ apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_HT_FREEZE);
++ } else
++ apec_setecmode(apec, channel, cOCT6100_ECHO_OP_MODE_DIGITAL);
++ }
++ printk("APEC: Setting EC on channel %d to %d\n", channel, eclen);
++}
++
++int apec_checkirq(struct apec_s *apec)
++{
++ tOCT6100_INTERRUPT_FLAGS InterruptFlags;
++
++ Oct6100InterruptServiceRoutineDef(&InterruptFlags);
++ Oct6100InterruptServiceRoutine(apec->pApiInstance, &InterruptFlags);
++
++ return InterruptFlags.fToneEventsPending ? 1 : 0;
++}
++
++unsigned int apec_capacity_get(void *wc)
++{
++ UINT32 ulResult;
++
++ tOCT6100_API_GET_CAPACITY_PINS CapacityPins;
++
++ Oct6100ApiGetCapacityPinsDef(&CapacityPins);
++ CapacityPins.pProcessContext = wc;
++ CapacityPins.ulMemoryType = cOCT6100_MEM_TYPE_DDR;
++ CapacityPins.fEnableMemClkOut = TRUE;
++ CapacityPins.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
++
++ ulResult = Oct6100ApiGetCapacityPins(&CapacityPins);
++ if (ulResult != cOCT6100_ERR_OK) {
++ printk("Failed to get chip capacity, code %08x!\n", ulResult);
++ return 0;
++ }
++ return CapacityPins.ulCapacityValue;
++}
++
++struct apec_s *apec_init(void *wc, int *isalaw, int numspans, const struct firmware *firmware)
++{
++ tOCT6100_CHIP_OPEN *ChipOpen;
++ tOCT6100_GET_INSTANCE_SIZE InstanceSize;
++ tOCT6100_CHANNEL_OPEN *ChannelOpen;
++ UINT32 ulResult;
++ struct apec_s *apec;
++ int x, law;
++#ifdef CONFIG_4KSTACKS
++ unsigned long flags;
++#endif
++
++ if (!(apec = kmalloc(sizeof(struct apec_s), GFP_KERNEL)))
++ return NULL;
++
++ memset(apec, 0, sizeof(struct apec_s));
++
++ if (!(ChipOpen = kmalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL))) {
++ kfree(apec);
++ return NULL;
++ }
++
++ memset(ChipOpen, 0, sizeof(tOCT6100_CHIP_OPEN));
++
++ if (!(ChannelOpen = kmalloc(sizeof(tOCT6100_CHANNEL_OPEN), GFP_KERNEL))) {
++ kfree(apec);
++ kfree(ChipOpen);
++ return NULL;
++ }
++
++ memset(ChannelOpen, 0, sizeof(tOCT6100_CHANNEL_OPEN));
++
++ for (x=0;x<128;x++)
++ apec->ecmode[x] = -1;
++
++ apec->numchans = numspans * 32;
++ printk("APEC: echo cancellation for %d channels\n", apec->numchans);
++
++ Oct6100ChipOpenDef(ChipOpen);
++
++ /* Setup Chip Open Parameters */
++ ChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ;
++ Oct6100GetInstanceSizeDef(&InstanceSize);
++
++ ChipOpen->pProcessContext = wc;
++
++ ChipOpen->pbyImageFile = firmware->data;
++ ChipOpen->ulImageSize = firmware->size;
++
++ ChipOpen->fEnableMemClkOut = TRUE;
++ ChipOpen->ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
++ ChipOpen->ulMaxChannels = apec->numchans;
++ ChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR;
++ ChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB;
++ ChipOpen->ulNumMemoryChips = 1;
++ ChipOpen->ulMaxTdmStreams = 4;
++ ChipOpen->aulTdmStreamFreqs[0] = cOCT6100_TDM_STREAM_FREQ_8MHZ;
++ ChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE;
++#if 0
++ ChipOpen->fEnableAcousticEcho = TRUE;
++#endif
++
++ ulResult = Oct6100GetInstanceSize(ChipOpen, &InstanceSize);
++ if (ulResult != cOCT6100_ERR_OK) {
++ printk("Failed to get instance size, code %08x!\n", ulResult);
++ kfree(apec);
++ return NULL;
++ }
++
++
++ apec->pApiInstance = vmalloc(InstanceSize.ulApiInstanceSize);
++ if (!apec->pApiInstance) {
++ printk("Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
++ kfree(apec);
++ kfree(ChipOpen);
++ kfree(ChannelOpen);
++ return NULL;
++ }
++
++ /* I don't know what to curse more in this comment, the problems caused by
++ * the 4K kernel stack limit change or the octasic API for being so darn
++ * stack unfriendly. Stupid, stupid, stupid. So we disable IRQs so we
++ * don't run the risk of overflowing the stack while we initialize the
++ * octasic. */
++#ifdef CONFIG_4KSTACKS
++ local_irq_save(flags);
++#endif
++ ulResult = Oct6100ChipOpen(apec->pApiInstance, ChipOpen);
++ if (ulResult != cOCT6100_ERR_OK) {
++ printk("Failed to open chip, code %08x!\n", ulResult);
++#ifdef CONFIG_4KSTACKS
++ local_irq_restore(flags);
++#endif
++ kfree(apec);
++ kfree(ChipOpen);
++ kfree(ChannelOpen);
++ return NULL;
++ }
++ for (x=0; x < 128; x++) {
++ /* execute this loop always on 4 span cards but
++ * on 2 span cards only execute for the channels related to our spans */
++ if ((x & 0x3) < numspans) {
++ /* span timeslots are interleaved 12341234...
++ * therefore, the lower 2 bits tell us which span this
++ * timeslot/channel
++ */
++ if (isalaw[x & 0x03])
++ law = cOCT6100_PCM_A_LAW;
++ else
++ law = cOCT6100_PCM_U_LAW;
++ Oct6100ChannelOpenDef(ChannelOpen);
++ ChannelOpen->pulChannelHndl = &apec->aulEchoChanHndl[x];
++ ChannelOpen->ulUserChanId = x;
++ ChannelOpen->TdmConfig.ulRinPcmLaw = law;
++ ChannelOpen->TdmConfig.ulRinStream = 0;
++ ChannelOpen->TdmConfig.ulRinTimeslot = x;
++ ChannelOpen->TdmConfig.ulSinPcmLaw = law;
++ ChannelOpen->TdmConfig.ulSinStream = 1;
++ ChannelOpen->TdmConfig.ulSinTimeslot = x;
++ ChannelOpen->TdmConfig.ulSoutPcmLaw = law;
++ ChannelOpen->TdmConfig.ulSoutStream = 2;
++ ChannelOpen->TdmConfig.ulSoutTimeslot = x;
++ ChannelOpen->TdmConfig.ulRoutPcmLaw = law;
++ ChannelOpen->TdmConfig.ulRoutStream = 3;
++ ChannelOpen->TdmConfig.ulRoutTimeslot = x;
++ ChannelOpen->VqeConfig.fEnableNlp = TRUE;
++ ChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE;
++ ChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE;
++
++ ChannelOpen->fEnableToneDisabler = TRUE;
++ ChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_DIGITAL;
++
++ ulResult = Oct6100ChannelOpen(apec->pApiInstance, ChannelOpen);
++ if (ulResult != GENERIC_OK) {
++ printk("Failed to open channel %d!\n", x);
++ }
++ }
++ }
++
++#ifdef CONFIG_4KSTACKS
++ local_irq_restore(flags);
++#endif
++ kfree(ChipOpen);
++ kfree(ChannelOpen);
++ return apec;
++}
++
++void apec_release(struct apec_s *apec)
++{
++ UINT32 ulResult;
++ tOCT6100_CHIP_CLOSE ChipClose;
++
++ Oct6100ChipCloseDef(&ChipClose);
++ ulResult = Oct6100ChipClose(apec->pApiInstance, &ChipClose);
++ if (ulResult != cOCT6100_ERR_OK) {
++ printk("Failed to close chip, code %08x!\n", ulResult);
++ }
++ vfree(apec->pApiInstance);
++ kfree(apec);
++ printk(KERN_INFO "APEC: Releasing...\n");
++}
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/ap400/apec.h dahdi-extra-dahdi-linux/drivers/dahdi/ap400/apec.h
+--- dahdi-linux-2.7.0/drivers/dahdi/ap400/apec.h 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/ap400/apec.h 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,48 @@
++/*
++ * AP400 Echo Cancelation Hardware support
++ *
++ * Written by Wagner Gegler <aligera@aligera.com.br>
++ *
++ * Based on previous work written by Mark Spencer <markster@digium.com>
++ *
++ * Copyright (C) 2005-2006 Digium, Inc.
++ *
++ * Mark Spencer <markster@digium.com>
++ *
++ * All Rights Reserved
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++#ifndef _APEC_H_
++#define _APEC_H_
++
++#include <linux/firmware.h>
++
++struct apec_s;
++
++/* From AP400 */
++unsigned int oct_read(void *card, unsigned int addr);
++void oct_write(void *card, unsigned int addr, unsigned int data);
++
++/* From APEC */
++struct apec_s *apec_init(void *wc, int *isalaw, int numspans, const struct firmware *firmware);
++unsigned int apec_capacity_get(void *wc);
++void apec_setec(struct apec_s *instance, int channel, int eclen);
++int apec_checkirq(struct apec_s *apec);
++void apec_release(struct apec_s *instance);
++
++#endif /*_APEC_H_*/
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/ap400/Kbuild dahdi-extra-dahdi-linux/drivers/dahdi/ap400/Kbuild
+--- dahdi-linux-2.7.0/drivers/dahdi/ap400/Kbuild 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/ap400/Kbuild 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,26 @@
++obj-m += ap400.o
++
++EXTRA_CFLAGS := -I$(src)/..
++
++ap400-objs := ap400_drv.o
++
++# APEC_SUPPORT
++ECHO_FIRMWARE := $(wildcard $(src)/OCT61*.ima)
++ifneq ($(strip $(ECHO_FIRMWARE)),)
++ EXTRA_CFLAGS+=-DAPEC_SUPPORT $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
++ ap400-objs += apec.o $(shell $(src)/../oct612x/octasic-helper objects ../oct612x) firmware_oct6104e-64d.o firmware_oct6104e-128d.o
++endif
++
++$(obj)/apec.o: $(src)/apec.h $(src)/../oct612x/include/oct6100api/oct6100_api.h
++
++$(obj)/firmware_oct6104e-64d.o: $(src)/OCT6104E-64D.ima $(obj)/ap400_drv.o $(src)/../firmware/make_firmware_object
++ @echo Making firmware object file for $(notdir $<)
++ @cd $(src) && ../firmware/make_firmware_object $(notdir $<) $@ $(obj)/ap400_drv.o
++
++$(obj)/firmware_oct6104e-128d.o: $(src)/OCT6104E-128D.ima $(obj)/ap400_drv.o $(src)/../firmware/make_firmware_object
++ @echo Making firmware object file for $(notdir $<)
++ @cd $(src) && ../firmware/make_firmware_object $(notdir $<) $@ $(obj)/ap400_drv.o
++
++$(src)/../firmware/make_firmware_object:
++ make -C $(src)/../firmware make_firmware_object
++
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/Kbuild dahdi-extra-dahdi-linux/drivers/dahdi/Kbuild
+--- dahdi-linux-2.7.0/drivers/dahdi/Kbuild 2013-06-07 20:29:39.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/Kbuild 2013-06-04 15:18:43.000000000 +0100
+@@ -39,6 +39,14 @@
+ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_KB1) += dahdi_echocan_kb1.o
+ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2) += dahdi_echocan_mg2.o
+
++ifdef CONFIG_PCI
++obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_AP400) += ap400/
++obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXA1200) += opvxa1200/
++obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXD115) += opvxd115/
++obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCOPENPCI) += wcopenpci.o
++obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ZAPHFC) += zaphfc/
++endif
++
+ obj-m += $(DAHDI_MODULES_EXTRA)
+
+ # If you want to build OSLEC, include the code in the standard location:
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/Kconfig dahdi-extra-dahdi-linux/drivers/dahdi/Kconfig
+--- dahdi-linux-2.7.0/drivers/dahdi/Kconfig 2013-06-07 20:29:39.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/Kconfig 2013-06-04 15:18:43.000000000 +0100
+@@ -292,3 +292,89 @@
+ If unsure, say Y.
+
+ source "drivers/dahdi/xpp/Kconfig"
++
++config DAHDI_AP4XX
++ tristate "Aligera AP4XX PCI Card Driver"
++ depends on DAHDI && PCI
++ default DAHDI
++ ---help---
++ This driver provides support for the Aligera AP400 quad-span
++ E1/T1 DAHDI cards:
++
++ To compile this driver as a module, choose M here: the
++ module will be called ap4xx.
++
++ If unsure, say Y.
++
++config DAHDI_OPVXA1200
++ tristate "OpenVox 8/12 ports analog card Support"
++ depends on DAHDI && PCI
++ default DAHDI
++ ---help---
++ This driver provides support for the following OpenVox
++ Wildcard products:
++
++ * A1200P (PCI)
++ * A1200E (PCI-E)
++ * A800P (PCI)
++ * A800E (PCI-E)
++
++ To compile this driver as a module, choose M here: the
++ module will be called opvxa1200.
++
++ If unsure, say Y.
++
++config DAHDI_OPVXD115
++ tristate "OpenVox Single-T1/E1/J1 Support"
++ depends on DAHDI && PCI
++ default DAHDI
++ ---help---
++ This driver provides support for the following OpenVox
++ Wildcard products:
++
++ * D115P/DE115P/D130P/DE130P (PCI)
++ * D115E/DE115E/D130E/DE130E (PCI-E)
++
++ To compile this driver as a module, choose M here: the
++ module will be called opvxd115.
++
++ If unsure, say Y.
++
++
++config DAHDI_WCOPENPCI
++ tristate "Voicetronix OpenPCI Interface DAHDI driver"
++ depends on DAHDI && PCI
++ default DAHDI
++ ---help---
++ This driver provides support for the Voicetronix OpenPCI Interface.
++
++ To compile this driver as a module, choose M here: the
++ module will be called wcopenpci.
++
++ If unsure, say Y.
++
++config DAHDI_ZAPHFC
++ tristate "HFC-S DAHDI Driver"
++ depends on DAHDI && PCI
++ default DAHDI
++ ---help---
++ This driver provides DAHDI support for various HFC-S single-port
++ ISDN (BRI) cards.
++
++ To compile this driver as a module, choose M here: the
++ module will be called zaphfc.
++
++ If unsure, say Y.
++
++config ECHO
++ tristate "Line Echo Canceller support"
++ default DAHDI
++ --help--
++ This driver provides line echo cancelling support for mISDN and
++ DAHDI drivers.
++
++ To compile this driver as a module, choose M here: the
++ module will be called echo.
++
++ If unsure, say Y.
++
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/opvxa1200/base.c dahdi-extra-dahdi-linux/drivers/dahdi/opvxa1200/base.c
+--- dahdi-linux-2.7.0/drivers/dahdi/opvxa1200/base.c 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/opvxa1200/base.c 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,3070 @@
++/*
++ * OpenVox A1200P FXS/FXO Interface Driver for DAHDI Telephony interface
++ *
++ * Written by MiaoLin<miaolin@openvox.cn>
++ *
++ * Copyright (C) 2005-2010 OpenVox Communication Co. Ltd,
++ *
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++/* Rev histroy
++ *
++ * Rev 0.10 initial version
++ * Rev 0.11
++ * fixed the led light on/off bug.
++ * modify some wctdm print to opvxa1200
++ * support firmware version 1.2, faster i/o operation, and better LED control.
++ *
++ * Rev 0.12 patched to support new pci id 0x8519
++ * Rev 0.13 patched to remove the warning during compile under kernel 2.6.22
++ * Rev 0.14 patched to remove the bug for ZAP_IRQ_SHARED , 3/9/2007
++ * Rev 0.15 patched to support new pci ID 0X9532 by james.zhu, 23/10/2007
++ * Rev 0.16 support new pci id 0x9559 by Miao Lin 21/3/2008
++ * Rev 0.17
++ * patched a few bugs,
++ * add hwgain support.
++ * fixed A800P version check
++ * Rev 1.4.9.2
++ * Only generate 8 channels for A800P
++ * Version number synced to zaptel distribution.
++ * Rev 1.4.9.2.a
++ * Fixed freeregion.
++ *
++ * Rev 1.4.9.2.b
++ * Add cid before first ring support.
++ * New Paremeters:
++ * cidbeforering : set to 1 will cause the card enable cidbeforering function. default 0
++ * cidbuflen : length of cid buffer, in msec, default 3000 msec.
++ * cidtimeout : time out of a ring, default 6000msec
++ * User must set cidstart=polarity in zapata.conf to use with this feature
++ * cidsignalling = signalling format send before 1st ring. most likely dtmf.
++ *
++ * Rev 1.4.9.2.c
++ * add driver parameter cidtimeout.
++ *
++ * Rev 1.4.9.2.d
++ * add debug stuff to test fxs power alarm
++ *
++ * Rev 1.4.11
++ * Support enhanced full scale tx/rx for FXO required by europe standard (Register 30, acim) (module parm fxofullscale)
++ *
++ * Rev 1.4.12 2008/10/17
++ * Fixed bug cause FXS module report fake power alarm.
++ * Power alarm debug stuff removed.
++ *
++ * Rev 2.0 DAHDI 2008/10/17
++ *
++ * Rev 2.0.1 add new pci id 0x9599
++ * Re 2.0.2 12/01/2009
++ add fixedtimepolarity: set time(ms) when send polarity after 1st ring happen.
++ * Sometimes the dtmf cid is sent just after first ring off, and the system do not have
++ * enough time to start detect 1st dtmf.
++ * 0 means send polarity at the end of 1st ring.
++ * x means send ploarity after x ms of 1st ring begin.
++ *
++ * Rev 2.0.3 12/01/2009
++ * Add touch_softlockup_watchdog() in wctdm_hardware_init, to avoid cpu softlockup system message for FXS.
++ *
++ *
++ * Rev 1.4.12.4 17/04/2009 James.zhu
++ * Changed wctdm_voicedaa_check_hook() to detect FXO battery and solved the problem with dial(dahdi/go/XXXXXXXXXX)
++ * add alarm detection for FXO
++ *
++ * Rev 1.4.12.5 01/10/2009 james.zhu
++ * Add jiffies for 5 second in wctdm_hardware_init
++ *
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/pci.h>
++#include <linux/interrupt.h>
++#include <linux/moduleparam.h>
++#include <linux/version.h>
++#include <asm/io.h>
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
++#include <linux/nmi.h>
++#else
++#include <linux/sched.h>
++#endif
++#include "proslic.h"
++
++/* MiaoLin debug start */
++#include <linux/string.h>
++#include <asm/uaccess.h> /* get_fs(), set_fs(), KERNEL_DS */
++#include <linux/file.h> /* fput() */
++/* MiaoLin debug end */
++
++
++/*
++ * Define for audio vs. register based ring detection
++ *
++ */
++/* #define AUDIO_RINGCHECK */
++
++/*
++ Experimental max loop current limit for the proslic
++ Loop current limit is from 20 mA to 41 mA in steps of 3
++ (according to datasheet)
++ So set the value below to:
++ 0x00 : 20mA (default)
++ 0x01 : 23mA
++ 0x02 : 26mA
++ 0x03 : 29mA
++ 0x04 : 32mA
++ 0x05 : 35mA
++ 0x06 : 37mA
++ 0x07 : 41mA
++*/
++static int loopcurrent = 20;
++
++static int reversepolarity = 0;
++
++static alpha indirect_regs[] =
++{
++{0,255,"DTMF_ROW_0_PEAK",0x55C2},
++{1,255,"DTMF_ROW_1_PEAK",0x51E6},
++{2,255,"DTMF_ROW2_PEAK",0x4B85},
++{3,255,"DTMF_ROW3_PEAK",0x4937},
++{4,255,"DTMF_COL1_PEAK",0x3333},
++{5,255,"DTMF_FWD_TWIST",0x0202},
++{6,255,"DTMF_RVS_TWIST",0x0202},
++{7,255,"DTMF_ROW_RATIO_TRES",0x0198},
++{8,255,"DTMF_COL_RATIO_TRES",0x0198},
++{9,255,"DTMF_ROW_2ND_ARM",0x0611},
++{10,255,"DTMF_COL_2ND_ARM",0x0202},
++{11,255,"DTMF_PWR_MIN_TRES",0x00E5},
++{12,255,"DTMF_OT_LIM_TRES",0x0A1C},
++{13,0,"OSC1_COEF",0x7B30},
++{14,1,"OSC1X",0x0063},
++{15,2,"OSC1Y",0x0000},
++{16,3,"OSC2_COEF",0x7870},
++{17,4,"OSC2X",0x007D},
++{18,5,"OSC2Y",0x0000},
++{19,6,"RING_V_OFF",0x0000},
++{20,7,"RING_OSC",0x7EF0},
++{21,8,"RING_X",0x0160},
++{22,9,"RING_Y",0x0000},
++{23,255,"PULSE_ENVEL",0x2000},
++{24,255,"PULSE_X",0x2000},
++{25,255,"PULSE_Y",0x0000},
++//{26,13,"RECV_DIGITAL_GAIN",0x4000}, // playback volume set lower
++{26,13,"RECV_DIGITAL_GAIN",0x2000}, // playback volume set lower
++{27,14,"XMIT_DIGITAL_GAIN",0x4000},
++//{27,14,"XMIT_DIGITAL_GAIN",0x2000},
++{28,15,"LOOP_CLOSE_TRES",0x1000},
++{29,16,"RING_TRIP_TRES",0x3600},
++{30,17,"COMMON_MIN_TRES",0x1000},
++{31,18,"COMMON_MAX_TRES",0x0200},
++{32,19,"PWR_ALARM_Q1Q2",0x07C0},
++{33,20,"PWR_ALARM_Q3Q4",0x2600},
++{34,21,"PWR_ALARM_Q5Q6",0x1B80},
++{35,22,"LOOP_CLOSURE_FILTER",0x8000},
++{36,23,"RING_TRIP_FILTER",0x0320},
++{37,24,"TERM_LP_POLE_Q1Q2",0x008C},
++{38,25,"TERM_LP_POLE_Q3Q4",0x0100},
++{39,26,"TERM_LP_POLE_Q5Q6",0x0010},
++{40,27,"CM_BIAS_RINGING",0x0C00},
++{41,64,"DCDC_MIN_V",0x0C00},
++{42,255,"DCDC_XTRA",0x1000},
++{43,66,"LOOP_CLOSE_TRES_LOW",0x1000},
++};
++
++
++#include <dahdi/kernel.h>
++#include <dahdi/wctdm_user.h>
++
++#include "fxo_modes.h"
++
++#define NUM_FXO_REGS 60
++
++#define WC_MAX_IFACES 128
++
++#define WC_OFFSET 4 /* Offset between transmit and receive, in bytes. */
++#define WC_SYNCFLAG 0xca1ef1ac
++
++#define WC_CNTL 0x00
++#define WC_OPER 0x01
++#define WC_AUXC 0x02
++#define WC_AUXD 0x03
++#define WC_MASK0 0x04
++#define WC_MASK1 0x05
++#define WC_INTSTAT 0x06
++#define WC_AUXR 0x07
++
++#define WC_DMAWS 0x08
++#define WC_DMAWI 0x0c
++#define WC_DMAWE 0x10
++#define WC_DMARS 0x18
++#define WC_DMARI 0x1c
++#define WC_DMARE 0x20
++
++#define WC_AUXFUNC 0x2b
++#define WC_SERCTL 0x2d
++#define WC_FSCDELAY 0x2f
++
++#define WC_REGBASE 0xc0
++
++#define WC_VER 0x0
++#define WC_CS 0x1
++#define WC_SPICTRL 0x2
++#define WC_SPIDATA 0x3
++
++#define BIT_SPI_BYHW (1 << 0)
++#define BIT_SPI_BUSY (1 << 1) // 0=can read/write spi, 1=spi working.
++#define BIT_SPI_START (1 << 2)
++
++
++#define BIT_LED_CLK (1 << 0) // MiaoLin add to control the led.
++#define BIT_LED_DATA (1 << 1) // MiaoLin add to control the led.
++
++#define BIT_CS (1 << 2)
++#define BIT_SCLK (1 << 3)
++#define BIT_SDI (1 << 4)
++#define BIT_SDO (1 << 5)
++
++#define FLAG_EMPTY 0
++#define FLAG_WRITE 1
++#define FLAG_READ 2
++#define DEFAULT_RING_DEBOUNCE 64 /* Ringer Debounce (64 ms) */
++#define POLARITY_DEBOUNCE 64 /* Polarity debounce (64 ms) */
++#define OHT_TIMER 6000 /* How long after RING to retain OHT */
++
++#define FLAG_3215 (1 << 0)
++#define FLAG_A800 (1 << 7)
++
++#define MAX_NUM_CARDS 12
++#define NUM_CARDS 12
++#define NUM_FLAG 4 /* number of flag channels. */
++
++
++enum cid_hook_state {
++ CID_STATE_IDLE = 0,
++ CID_STATE_RING_ON,
++ CID_STATE_RING_OFF,
++ CID_STATE_WAIT_RING_FINISH
++};
++
++/* if you want to record the last 8 sec voice before the driver unload, uncomment it and rebuild. */
++/* #define TEST_LOG_INCOME_VOICE */
++#define voc_buffer_size (8000*8)
++
++
++#define MAX_ALARMS 10
++
++#define MOD_TYPE_FXS 0
++#define MOD_TYPE_FXO 1
++
++#define MINPEGTIME 10 * 8 /* 30 ms peak to peak gets us no more than 100 Hz */
++#define PEGTIME 50 * 8 /* 50ms peak to peak gets us rings of 10 Hz or more */
++#define PEGCOUNT 5 /* 5 cycles of pegging means RING */
++
++#define NUM_CAL_REGS 12
++
++struct calregs {
++ unsigned char vals[NUM_CAL_REGS];
++};
++
++enum proslic_power_warn {
++ PROSLIC_POWER_UNKNOWN = 0,
++ PROSLIC_POWER_ON,
++ PROSLIC_POWER_WARNED,
++};
++
++enum battery_state {
++ BATTERY_UNKNOWN = 0,
++ BATTERY_PRESENT,
++ BATTERY_LOST,
++};
++struct wctdm {
++ struct pci_dev *dev;
++ char *variety;
++ struct dahdi_span span;
++ struct dahdi_device *ddev;
++ unsigned char ios;
++ int usecount;
++ unsigned int intcount;
++ int dead;
++ int pos;
++ int flags[MAX_NUM_CARDS];
++ int freeregion;
++ int alt;
++ int curcard;
++ int cardflag; /* Bit-map of present cards */
++ enum proslic_power_warn proslic_power;
++ spinlock_t lock;
++
++ union {
++ struct fxo {
++#ifdef AUDIO_RINGCHECK
++ unsigned int pegtimer;
++ int pegcount;
++ int peg;
++ int ring;
++#else
++ int wasringing;
++ int lastrdtx;
++#endif
++ int ringdebounce;
++ int offhook;
++ unsigned int battdebounce;
++ unsigned int battalarm;
++ enum battery_state battery;
++ int lastpol;
++ int polarity;
++ int polaritydebounce;
++ } fxo;
++ struct fxs {
++ int oldrxhook;
++ int debouncehook;
++ int lastrxhook;
++ int debounce;
++ int ohttimer;
++ int idletxhookstate; /* IDLE changing hook state */
++ int lasttxhook;
++ int palarms;
++ struct calregs calregs;
++ } fxs;
++ } mod[MAX_NUM_CARDS];
++
++ /* Receive hook state and debouncing */
++ int modtype[MAX_NUM_CARDS];
++ unsigned char reg0shadow[MAX_NUM_CARDS];
++ unsigned char reg1shadow[MAX_NUM_CARDS];
++
++ unsigned long ioaddr;
++ unsigned long mem_region; /* 32 bit Region allocated to tiger320 */
++ unsigned long mem_len; /* Length of 32 bit region */
++ volatile unsigned long mem32; /* Virtual representation of 32 bit memory area */
++
++ dma_addr_t readdma;
++ dma_addr_t writedma;
++ volatile unsigned char *writechunk; /* Double-word aligned write memory */
++ volatile unsigned char *readchunk; /* Double-word aligned read memory */
++ /*struct dahdi_chan chans[MAX_NUM_CARDS];*/
++ struct dahdi_chan _chans[NUM_CARDS];
++ struct dahdi_chan *chans[NUM_CARDS];
++
++
++#ifdef TEST_LOG_INCOME_VOICE
++ char * voc_buf[MAX_NUM_CARDS + NUM_FLAG];
++ int voc_ptr[MAX_NUM_CARDS + NUM_FLAG];
++#endif
++ int lastchan;
++ unsigned short ledstate;
++ unsigned char fwversion;
++ int max_cards;
++ char *card_name;
++
++ char *cid_history_buf[MAX_NUM_CARDS];
++ int cid_history_ptr[MAX_NUM_CARDS];
++ int cid_history_clone_cnt[MAX_NUM_CARDS];
++ enum cid_hook_state cid_state[MAX_NUM_CARDS];
++ int cid_ring_on_time[MAX_NUM_CARDS];
++};
++
++static char* A1200P_Name = "A1200P";
++static char* A800P_Name = "A800P";
++
++struct wctdm_desc {
++ char *name;
++ int flags;
++};
++
++static struct wctdm_desc wctdme = { "OpenVox A1200P/A800P", 0 };
++static int acim2tiss[16] = { 0x0, 0x1, 0x4, 0x5, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2, 0x0, 0x3 };
++
++static struct wctdm *ifaces[WC_MAX_IFACES];
++
++static void wctdm_release(struct wctdm *wc);
++
++static unsigned int battdebounce;
++static unsigned int battalarm;
++static unsigned int battthresh;
++static int ringdebounce = DEFAULT_RING_DEBOUNCE;
++/* times 4, because must be a multiple of 4ms: */
++static int dialdebounce = 8 * 8;
++static int fwringdetect = 0;
++static int debug = 0;
++static int robust = 0;
++static int timingonly = 0;
++static int lowpower = 0;
++static int boostringer = 0;
++static int fastringer = 0;
++static int _opermode = 0;
++static char *opermode = "FCC";
++static int fxshonormode = 0;
++static int alawoverride = 0;
++static int fastpickup = 0;
++static int fxotxgain = 0;
++static int fxorxgain = 0;
++static int fxstxgain = 0;
++static int fxsrxgain = 0;
++/* special h/w control command */
++static int spibyhw = 1;
++static int usememio = 1;
++static int cidbeforering = 0;
++static int cidbuflen = 3000; /* in msec, default 3000 */
++static int cidtimeout = 6*1000; /* in msec, default 6000 */
++static int fxofullscale = 0; /* fxo full scale tx/rx, register 30, acim */
++static int fixedtimepolarity=0; /* time delay in ms when send polarity after rise edge of 1st ring.*/
++
++static int wctdm_init_proslic(struct wctdm *wc, int card, int fast , int manual, int sane);
++
++static void wctdm_set_led(struct wctdm* wc, int card, int onoff)
++{
++ int i;
++ unsigned char c;
++
++ wc->ledstate &= ~(0x01<<card);
++ wc->ledstate |= (onoff<<card);
++ c = (inb(wc->ioaddr + WC_AUXD)&~BIT_LED_CLK)|BIT_LED_DATA;
++ outb( c, wc->ioaddr + WC_AUXD);
++ for(i=MAX_NUM_CARDS-1; i>=0; i--)
++ {
++ if(wc->ledstate & (0x0001<<i))
++ if(wc->fwversion == 0x11)
++ c &= ~BIT_LED_DATA;
++ else
++ c |= BIT_LED_DATA;
++ else
++ if(wc->fwversion == 0x11)
++ c |= BIT_LED_DATA;
++ else
++ c &= ~BIT_LED_DATA;
++
++ outb( c, wc->ioaddr + WC_AUXD);
++ outb( c|BIT_LED_CLK, wc->ioaddr + WC_AUXD);
++ outb( (c&~BIT_LED_CLK)|BIT_LED_DATA, wc->ioaddr + WC_AUXD);
++ }
++}
++
++
++static inline void wctdm_transmitprep(struct wctdm *wc, unsigned char ints)
++{
++ int x, y, chan_offset, pos;
++ volatile unsigned char *txbuf;
++
++ if (ints & /*0x01*/ 0x04)
++ /* Write is at interrupt address. Start writing from normal offset */
++ txbuf = wc->writechunk;
++ else
++ txbuf = wc->writechunk + DAHDI_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG);
++
++ /* Calculate Transmission */
++ dahdi_transmit(&wc->span);
++
++ if(wc->lastchan == -1) // not in sync.
++ return;
++
++ chan_offset = (wc->lastchan*4 + 4 ) % (MAX_NUM_CARDS+NUM_FLAG);
++
++ for (y=0;y<DAHDI_CHUNKSIZE;y++) {
++#ifdef __BIG_ENDIAN
++ // operation pending...
++#else
++ for (x=0;x<(MAX_NUM_CARDS+NUM_FLAG);x++) {
++ pos = y * (MAX_NUM_CARDS+NUM_FLAG) + ((x + chan_offset + MAX_NUM_CARDS+NUM_FLAG - WC_OFFSET)&0x0f);
++ if(x<wc->max_cards/*MAX_NUM_CARDS*/)
++ txbuf[pos] = wc->chans[x]->writechunk[y];
++ else
++ txbuf[pos] = 0;
++ }
++#endif
++ }
++}
++
++
++#ifdef AUDIO_RINGCHECK
++static inline void ring_check(struct wctdm *wc, int card)
++{
++ int x;
++ short sample;
++ if (wc->modtype[card] != MOD_TYPE_FXO)
++ return;
++ wc->mod[card].fxo.pegtimer += DAHDI_CHUNKSIZE;
++ for (x=0;x<DAHDI_CHUNKSIZE;x++) {
++ /* Look for pegging to indicate ringing */
++ sample = DAHDI_XLAW(wc->chans[card].readchunk[x], (&(wc->chans[card])));
++ if ((sample > 10000) && (wc->mod[card].fxo.peg != 1)) {
++ if (debug > 1) printk(KERN_DEBUG "High peg!\n");
++ if ((wc->mod[card].fxo.pegtimer < PEGTIME) && (wc->mod[card].fxo.pegtimer > MINPEGTIME))
++ wc->mod[card].fxo.pegcount++;
++ wc->mod[card].fxo.pegtimer = 0;
++ wc->mod[card].fxo.peg = 1;
++ } else if ((sample < -10000) && (wc->mod[card].fxo.peg != -1)) {
++ if (debug > 1) printk(KERN_DEBUG "Low peg!\n");
++ if ((wc->mod[card].fxo.pegtimer < (PEGTIME >> 2)) && (wc->mod[card].fxo.pegtimer > (MINPEGTIME >> 2)))
++ wc->mod[card].fxo.pegcount++;
++ wc->mod[card].fxo.pegtimer = 0;
++ wc->mod[card].fxo.peg = -1;
++ }
++ }
++ if (wc->mod[card].fxo.pegtimer > PEGTIME) {
++ /* Reset pegcount if our timer expires */
++ wc->mod[card].fxo.pegcount = 0;
++ }
++ /* Decrement debouncer if appropriate */
++ if (wc->mod[card].fxo.ringdebounce)
++ wc->mod[card].fxo.ringdebounce--;
++ if (!wc->mod[card].fxo.offhook && !wc->mod[card].fxo.ringdebounce) {
++ if (!wc->mod[card].fxo.ring && (wc->mod[card].fxo.pegcount > PEGCOUNT)) {
++ /* It's ringing */
++ if (debug)
++ printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
++ if (!wc->mod[card].fxo.offhook)
++ dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_RING);
++ wc->mod[card].fxo.ring = 1;
++ }
++ if (wc->mod[card].fxo.ring && !wc->mod[card].fxo.pegcount) {
++ /* No more ring */
++ if (debug)
++ printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
++ dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
++ wc->mod[card].fxo.ring = 0;
++ }
++ }
++}
++#endif
++
++
++static inline void wctdm_receiveprep(struct wctdm *wc, unsigned char ints)
++{
++ volatile unsigned char *rxbuf;
++ int x, y, chan_offset;
++
++
++ if (ints & 0x08/*0x04*/)
++ /* Read is at interrupt address. Valid data is available at normal offset */
++ rxbuf = wc->readchunk;
++ else
++ rxbuf = wc->readchunk + DAHDI_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG);
++
++ for(x=0; x<4; x++)
++ if( *(int*)(rxbuf+x*4) == WC_SYNCFLAG)
++ break;
++ if(x==4)
++ {
++ printk("buffer sync misseed!\n");
++ wc->lastchan = -1;
++ return;
++ }
++ else if(wc->lastchan != x)
++ {
++ printk("buffer re-sync occur from %d to %d\n", wc->lastchan, x);
++ wc->lastchan = x;
++ }
++ chan_offset = (wc->lastchan*4 + 4 ) % (MAX_NUM_CARDS+NUM_FLAG);
++
++ for (x=0;x<DAHDI_CHUNKSIZE;x++) {
++#ifdef __BIG_ENDIAN
++ // operation pending...
++#else
++ for (y=0;y<wc->max_cards/*MAX_NUM_CARDS*/;y++) {
++ if (wc->cardflag & (1 << y))
++ wc->chans[y]->readchunk[x] = rxbuf[(MAX_NUM_CARDS+NUM_FLAG) * x + ((y + chan_offset ) & 0x0f)];
++#ifdef TEST_LOG_INCOME_VOICE
++ wc->voc_buf[y][wc->voc_ptr[y]] = rxbuf[(MAX_NUM_CARDS+NUM_FLAG) * x + ((y + chan_offset) & 0x0f)];
++ wc->voc_ptr[y]++;
++ if(wc->voc_ptr[y] >= voc_buffer_size)
++ wc->voc_ptr[y] = 0;
++#endif
++ }
++#endif
++ }
++
++ if(cidbeforering)
++ {
++ for(x=0; x<wc->max_cards; x++)
++ {
++ if (wc->modtype[wc->chans[x]->chanpos - 1] == MOD_TYPE_FXO)
++ if(wc->mod[wc->chans[x]->chanpos - 1].fxo.offhook == 0)
++ {
++ /*unsigned int *p_readchunk, *p_cid_history;
++
++ p_readchunk = (unsigned int*)wc->chans[x].readchunk;
++ p_cid_history = (unsigned int*)(wc->cid_history_buf[x] + wc->cid_history_ptr[x]);*/
++
++ if(wc->cid_state[x] == CID_STATE_IDLE) /* we need copy data to the cid voice buffer */
++ {
++ memcpy(wc->cid_history_buf[x] + wc->cid_history_ptr[x], wc->chans[x]->readchunk, DAHDI_CHUNKSIZE);
++ wc->cid_history_ptr[x] = (wc->cid_history_ptr[x] + DAHDI_CHUNKSIZE)%(cidbuflen * DAHDI_MAX_CHUNKSIZE);
++ }
++ else if (wc->cid_state[x] == CID_STATE_RING_ON)
++ wc->cid_history_clone_cnt[x] = cidbuflen;
++ else if (wc->cid_state[x] == CID_STATE_RING_OFF)
++ {
++ if(wc->cid_history_clone_cnt[x])
++ {
++ memcpy(wc->chans[x]->readchunk, wc->cid_history_buf[x] + wc->cid_history_ptr[x], DAHDI_MAX_CHUNKSIZE);
++ wc->cid_history_clone_cnt[x]--;
++ wc->cid_history_ptr[x] = (wc->cid_history_ptr[x] + DAHDI_MAX_CHUNKSIZE)%(cidbuflen * DAHDI_MAX_CHUNKSIZE);
++ }
++ else
++ {
++ wc->cid_state[x] = CID_STATE_WAIT_RING_FINISH;
++ wc->cid_history_clone_cnt[x] = cidtimeout; /* wait 6 sec, if no ring, return to idle */
++ }
++ }
++ else if(wc->cid_state[x] == CID_STATE_WAIT_RING_FINISH)
++ {
++ if(wc->cid_history_clone_cnt[x] > 0)
++ wc->cid_history_clone_cnt[x]--;
++ else
++ {
++ wc->cid_state[x] = CID_STATE_IDLE;
++ wc->cid_history_ptr[x] = 0;
++ wc->cid_history_clone_cnt[x] = 0;
++ }
++ }
++ }
++ }
++ }
++
++#ifdef AUDIO_RINGCHECK
++ for (x=0;x<wc->max_cards;x++)
++ ring_check(wc, x);
++#endif
++ /* XXX We're wasting 8 taps. We should get closer :( */
++ for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
++ if (wc->cardflag & (1 << x))
++ dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->chans[x]->writechunk);
++ }
++ dahdi_receive(&wc->span);
++}
++
++static void wctdm_stop_dma(struct wctdm *wc);
++static void wctdm_reset_tdm(struct wctdm *wc);
++static void wctdm_restart_dma(struct wctdm *wc);
++
++
++static unsigned char __wctdm_getcreg(struct wctdm *wc, unsigned char reg);
++static void __wctdm_setcreg(struct wctdm *wc, unsigned char reg, unsigned char val);
++
++
++static inline void __write_8bits(struct wctdm *wc, unsigned char bits)
++{
++ if(spibyhw == 0)
++ {
++ int x;
++ /* Drop chip select */
++ wc->ios |= BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ wc->ios &= ~BIT_CS;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ for (x=0;x<8;x++) {
++ /* Send out each bit, MSB first, drop SCLK as we do so */
++ if (bits & 0x80)
++ wc->ios |= BIT_SDI;
++ else
++ wc->ios &= ~BIT_SDI;
++ wc->ios &= ~BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ /* Now raise SCLK high again and repeat */
++ wc->ios |= BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ bits <<= 1;
++ }
++ /* Finally raise CS back high again */
++ wc->ios |= BIT_CS;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ }
++ else
++ {
++ __wctdm_setcreg(wc, WC_SPIDATA, bits);
++ __wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW | BIT_SPI_START);
++ while ((__wctdm_getcreg(wc, WC_SPICTRL) & BIT_SPI_BUSY) != 0);
++ __wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);
++ }
++}
++
++
++static inline void __reset_spi(struct wctdm *wc)
++{
++ __wctdm_setcreg(wc, WC_SPICTRL, 0);
++
++ /* Drop chip select and clock once and raise and clock once */
++ wc->ios |= BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ wc->ios &= ~BIT_CS;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ wc->ios |= BIT_SDI;
++ wc->ios &= ~BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ /* Now raise SCLK high again and repeat */
++ wc->ios |= BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ /* Finally raise CS back high again */
++ wc->ios |= BIT_CS;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ /* Clock again */
++ wc->ios &= ~BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ /* Now raise SCLK high again and repeat */
++ wc->ios |= BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++
++ __wctdm_setcreg(wc, WC_SPICTRL, spibyhw);
++
++}
++
++static inline unsigned char __read_8bits(struct wctdm *wc)
++{
++ unsigned char res=0, c;
++ int x;
++ if(spibyhw == 0)
++ {
++ wc->ios &= ~BIT_CS;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ /* Drop chip select */
++ wc->ios &= ~BIT_CS;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ for (x=0;x<8;x++) {
++ res <<= 1;
++ /* Get SCLK */
++ wc->ios &= ~BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ /* Read back the value */
++ c = inb(wc->ioaddr + WC_AUXR);
++ if (c & BIT_SDO)
++ res |= 1;
++ /* Now raise SCLK high again */
++ wc->ios |= BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ }
++ /* Finally raise CS back high again */
++ wc->ios |= BIT_CS;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ wc->ios &= ~BIT_SCLK;
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++ }
++ else
++ {
++ __wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW | BIT_SPI_START);
++ while ((__wctdm_getcreg(wc, WC_SPICTRL) & BIT_SPI_BUSY) != 0);
++ res = __wctdm_getcreg(wc, WC_SPIDATA);
++ __wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW);
++ }
++
++ /* And return our result */
++ return res;
++}
++
++static void __wctdm_setcreg_mem(struct wctdm *wc, unsigned char reg, unsigned char val)
++{
++ unsigned int *p = (unsigned int*)(wc->mem32 + WC_REGBASE + ((reg & 0xf) << 2));
++ *p = val;
++}
++
++static unsigned char __wctdm_getcreg_mem(struct wctdm *wc, unsigned char reg)
++{
++ unsigned int *p = (unsigned int*)(wc->mem32 + WC_REGBASE + ((reg & 0xf) << 2));
++ return (*p)&0x00ff;
++}
++
++
++static void __wctdm_setcreg(struct wctdm *wc, unsigned char reg, unsigned char val)
++{
++ if(usememio)
++ __wctdm_setcreg_mem(wc, reg, val);
++ else
++ outb(val, wc->ioaddr + WC_REGBASE + ((reg & 0xf) << 2));
++}
++
++static unsigned char __wctdm_getcreg(struct wctdm *wc, unsigned char reg)
++{
++ if(usememio)
++ return __wctdm_getcreg_mem(wc, reg);
++ else
++ return inb(wc->ioaddr + WC_REGBASE + ((reg & 0xf) << 2));
++}
++
++static inline void __wctdm_setcard(struct wctdm *wc, int card)
++{
++ if (wc->curcard != card) {
++ __wctdm_setcreg(wc, WC_CS, card);
++ wc->curcard = card;
++ //printk("Select card %d\n", card);
++ }
++}
++
++static void __wctdm_setreg(struct wctdm *wc, int card, unsigned char reg, unsigned char value)
++{
++ __wctdm_setcard(wc, card);
++ if (wc->modtype[card] == MOD_TYPE_FXO) {
++ __write_8bits(wc, 0x20);
++ __write_8bits(wc, reg & 0x7f);
++ } else {
++ __write_8bits(wc, reg & 0x7f);
++ }
++ __write_8bits(wc, value);
++}
++
++static void wctdm_setreg(struct wctdm *wc, int card, unsigned char reg, unsigned char value)
++{
++ unsigned long flags;
++ spin_lock_irqsave(&wc->lock, flags);
++ __wctdm_setreg(wc, card, reg, value);
++ spin_unlock_irqrestore(&wc->lock, flags);
++}
++
++static unsigned char __wctdm_getreg(struct wctdm *wc, int card, unsigned char reg)
++{
++ __wctdm_setcard(wc, card);
++ if (wc->modtype[card] == MOD_TYPE_FXO) {
++ __write_8bits(wc, 0x60);
++ __write_8bits(wc, reg & 0x7f);
++ } else {
++ __write_8bits(wc, reg | 0x80);
++ }
++ return __read_8bits(wc);
++}
++
++static inline void reset_spi(struct wctdm *wc, int card)
++{
++ unsigned long flags;
++ spin_lock_irqsave(&wc->lock, flags);
++ __wctdm_setcard(wc, card);
++ __reset_spi(wc);
++ __reset_spi(wc);
++ spin_unlock_irqrestore(&wc->lock, flags);
++}
++
++static unsigned char wctdm_getreg(struct wctdm *wc, int card, unsigned char reg)
++{
++ unsigned long flags;
++ unsigned char res;
++ spin_lock_irqsave(&wc->lock, flags);
++ res = __wctdm_getreg(wc, card, reg);
++ spin_unlock_irqrestore(&wc->lock, flags);
++ return res;
++}
++
++static int __wait_access(struct wctdm *wc, int card)
++{
++ unsigned char data = 0;
++ long origjiffies;
++ int count = 0;
++
++ #define MAX 6000 /* attempts */
++
++
++ origjiffies = jiffies;
++ /* Wait for indirect access */
++ while (count++ < MAX)
++ {
++ data = __wctdm_getreg(wc, card, I_STATUS);
++
++ if (!data)
++ return 0;
++
++ }
++
++ if(count > (MAX-1)) printk(KERN_NOTICE " ##### Loop error (%02x) #####\n", data);
++
++ return 0;
++}
++
++static unsigned char translate_3215(unsigned char address)
++{
++ int x;
++ for (x=0;x<sizeof(indirect_regs)/sizeof(indirect_regs[0]);x++) {
++ if (indirect_regs[x].address == address) {
++ address = indirect_regs[x].altaddr;
++ break;
++ }
++ }
++ return address;
++}
++
++static int wctdm_proslic_setreg_indirect(struct wctdm *wc, int card, unsigned char address, unsigned short data)
++{
++ unsigned long flags;
++ int res = -1;
++ /* Translate 3215 addresses */
++ if (wc->flags[card] & FLAG_3215) {
++ address = translate_3215(address);
++ if (address == 255)
++ return 0;
++ }
++ spin_lock_irqsave(&wc->lock, flags);
++ if(!__wait_access(wc, card)) {
++ __wctdm_setreg(wc, card, IDA_LO,(unsigned char)(data & 0xFF));
++ __wctdm_setreg(wc, card, IDA_HI,(unsigned char)((data & 0xFF00)>>8));
++ __wctdm_setreg(wc, card, IAA,address);
++ res = 0;
++ };
++ spin_unlock_irqrestore(&wc->lock, flags);
++ return res;
++}
++
++static int wctdm_proslic_getreg_indirect(struct wctdm *wc, int card, unsigned char address)
++{
++ unsigned long flags;
++ int res = -1;
++ char *p=NULL;
++ /* Translate 3215 addresses */
++ if (wc->flags[card] & FLAG_3215) {
++ address = translate_3215(address);
++ if (address == 255)
++ return 0;
++ }
++ spin_lock_irqsave(&wc->lock, flags);
++ if (!__wait_access(wc, card)) {
++ __wctdm_setreg(wc, card, IAA, address);
++ if (!__wait_access(wc, card)) {
++ unsigned char data1, data2;
++ data1 = __wctdm_getreg(wc, card, IDA_LO);
++ data2 = __wctdm_getreg(wc, card, IDA_HI);
++ res = data1 | (data2 << 8);
++ } else
++ p = "Failed to wait inside\n";
++ } else
++ p = "failed to wait\n";
++ spin_unlock_irqrestore(&wc->lock, flags);
++ if (p)
++ printk(KERN_NOTICE "%s", p);
++ return res;
++}
++
++static int wctdm_proslic_init_indirect_regs(struct wctdm *wc, int card)
++{
++ unsigned char i;
++
++ for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++)
++ {
++ if(wctdm_proslic_setreg_indirect(wc, card, indirect_regs[i].address,indirect_regs[i].initial))
++ return -1;
++ }
++
++ return 0;
++}
++
++static int wctdm_proslic_verify_indirect_regs(struct wctdm *wc, int card)
++{
++ int passed = 1;
++ unsigned short i, initial;
++ int j;
++
++ for (i=0; i<sizeof(indirect_regs) / sizeof(indirect_regs[0]); i++)
++ {
++ if((j = wctdm_proslic_getreg_indirect(wc, card, (unsigned char) indirect_regs[i].address)) < 0) {
++ printk(KERN_NOTICE "Failed to read indirect register %d\n", i);
++ return -1;
++ }
++ initial= indirect_regs[i].initial;
++
++ if ( j != initial && (!(wc->flags[card] & FLAG_3215) || (indirect_regs[i].altaddr != 255)))
++ {
++ printk(KERN_NOTICE "!!!!!!! %s iREG %X = %X should be %X\n",
++ indirect_regs[i].name,indirect_regs[i].address,j,initial );
++ passed = 0;
++ }
++ }
++
++ if (passed) {
++ if (debug)
++ printk(KERN_DEBUG "Init Indirect Registers completed successfully.\n");
++ } else {
++ printk(KERN_NOTICE " !!!!! Init Indirect Registers UNSUCCESSFULLY.\n");
++ return -1;
++ }
++ return 0;
++}
++
++static inline void wctdm_proslic_recheck_sanity(struct wctdm *wc, int card)
++{
++ int res;
++ /* Check loopback */
++ res = wc->reg1shadow[card];
++
++ if (!res && (res != wc->mod[card].fxs.lasttxhook)) // read real state from register By wx
++ res=wctdm_getreg(wc, card, 64);
++
++ if (!res && (res != wc->mod[card].fxs.lasttxhook)) {
++ res = wctdm_getreg(wc, card, 8);
++ if (res) {
++ printk(KERN_NOTICE "Ouch, part reset, quickly restoring reality (%d)\n", card);
++ wctdm_init_proslic(wc, card, 1, 0, 1);
++ } else {
++ if (wc->mod[card].fxs.palarms++ < MAX_ALARMS) {
++ printk(KERN_NOTICE "Power alarm on module %d, resetting!\n", card + 1);
++ if (wc->mod[card].fxs.lasttxhook == 4)
++ wc->mod[card].fxs.lasttxhook = 1;
++ wctdm_setreg(wc, card, 64, wc->mod[card].fxs.lasttxhook);
++ } else {
++ if (wc->mod[card].fxs.palarms == MAX_ALARMS)
++ printk(KERN_NOTICE "Too many power alarms on card %d, NOT resetting!\n", card + 1);
++ }
++ }
++ }
++}
++static inline void wctdm_voicedaa_check_hook(struct wctdm *wc, int card)
++{
++#define MS_PER_CHECK_HOOK 16
++
++#ifndef AUDIO_RINGCHECK
++ unsigned char res;
++#endif
++ signed char b;
++ int errors = 0;
++ struct fxo *fxo = &wc->mod[card].fxo;
++
++ /* Try to track issues that plague slot one FXO's */
++ b = wc->reg0shadow[card];
++ if ((b & 0x2) || !(b & 0x8)) {
++ /* Not good -- don't look at anything else */
++ if (debug)
++ printk(KERN_DEBUG "Error (%02x) on card %d!\n", b, card + 1);
++ errors++;
++ }
++ b &= 0x9b;
++ if (fxo->offhook) {
++ if (b != 0x9)
++ wctdm_setreg(wc, card, 5, 0x9);
++ } else {
++ if (b != 0x8)
++ wctdm_setreg(wc, card, 5, 0x8);
++ }
++ if (errors)
++ return;
++ if (!fxo->offhook) {
++ if(fixedtimepolarity) {
++ if ( wc->cid_state[card] == CID_STATE_RING_ON && wc->cid_ring_on_time[card]>0)
++ {
++ if(wc->cid_ring_on_time[card]>=fixedtimepolarity )
++ {
++ dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
++ wc->cid_ring_on_time[card] = -1; /* the polarity already sent */
++ }
++ else
++ wc->cid_ring_on_time[card] += 16;
++ }
++}
++ if (fwringdetect) {
++ res = wc->reg0shadow[card] & 0x60;
++ if (fxo->ringdebounce) {
++ --fxo->ringdebounce;
++ if (res && (res != fxo->lastrdtx) &&
++ (fxo->battery == BATTERY_PRESENT)) {
++ if (!fxo->wasringing) {
++ fxo->wasringing = 1;
++ if (debug)
++ printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
++ if(cidbeforering)
++ {
++ if(wc->cid_state[card] == CID_STATE_IDLE)
++ {
++ wc->cid_state[card] = CID_STATE_RING_ON;
++ wc->cid_ring_on_time[card] = 16; /* check every 16ms */
++ }
++ else
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
++ }
++ else
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
++ }
++ fxo->lastrdtx = res;
++ fxo->ringdebounce = 10;
++ } else if (!res) {
++ if ((fxo->ringdebounce == 0) && fxo->wasringing) {
++ fxo->wasringing = 0;
++ if (debug)
++ printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
++ if(cidbeforering)
++ {
++ if(wc->cid_state[card] == CID_STATE_RING_ON)
++ {
++ if(fixedtimepolarity==0)
++ dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
++ wc->cid_state[card] = CID_STATE_RING_OFF;
++ }
++ else
++ {
++ if(wc->cid_state[card] == CID_STATE_WAIT_RING_FINISH)
++ wc->cid_history_clone_cnt[card] = cidtimeout;
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
++ }
++ }
++ else
++
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
++ }
++ }
++ } else if (res && (fxo->battery == BATTERY_PRESENT)) {
++ fxo->lastrdtx = res;
++ fxo->ringdebounce = 10;
++ }
++ } else {
++ res = wc->reg0shadow[card];
++ if ((res & 0x60) && (fxo->battery == BATTERY_PRESENT)) {
++ fxo->ringdebounce += (DAHDI_CHUNKSIZE * 16);
++ if (fxo->ringdebounce >= DAHDI_CHUNKSIZE * ringdebounce) {
++ if (!fxo->wasringing) {
++ fxo->wasringing = 1;
++ if(cidbeforering)
++ {
++ if(wc->cid_state[card] == CID_STATE_IDLE)
++ {
++ wc->cid_state[card] = CID_STATE_RING_ON;
++ wc->cid_ring_on_time[card] = 16; /* check every 16ms */
++ }
++ else
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
++ }
++ else
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_RING);
++ if (debug)
++ printk(KERN_DEBUG "RING on %d/%d!\n", wc->span.spanno, card + 1);
++ }
++ fxo->ringdebounce = DAHDI_CHUNKSIZE * ringdebounce;
++ }
++ } else {
++ fxo->ringdebounce -= DAHDI_CHUNKSIZE * 4;
++ if (fxo->ringdebounce <= 0) {
++ if (fxo->wasringing) {
++ fxo->wasringing = 0;
++ if(cidbeforering)
++ {
++ if(wc->cid_state[card] == CID_STATE_RING_ON)
++ {
++ if(fixedtimepolarity==0)
++ dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
++ wc->cid_state[card] = CID_STATE_RING_OFF;
++ }
++ else
++ {
++ if(wc->cid_state[card] == CID_STATE_WAIT_RING_FINISH)
++ wc->cid_history_clone_cnt[card] = cidtimeout;
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
++ }
++ }
++ else
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
++ if (debug)
++ printk(KERN_DEBUG "NO RING on %d/%d!\n", wc->span.spanno, card + 1);
++ }
++ fxo->ringdebounce = 0;
++ }
++ }
++ }
++ }
++
++ b = wc->reg1shadow[card];
++ if (abs(b) < battthresh) {
++ /* possible existing states:
++ battery lost, no debounce timer
++ battery lost, debounce timer (going to battery present)
++ battery present or unknown, no debounce timer
++ battery present or unknown, debounce timer (going to battery lost)
++ */
++
++ if (fxo->battery == BATTERY_LOST) {
++ if (fxo->battdebounce) {
++ /* we were going to BATTERY_PRESENT, but battery was lost again,
++ so clear the debounce timer */
++ fxo->battdebounce = 0;
++ }
++ } else {
++ if (fxo->battdebounce) {
++ /* going to BATTERY_LOST, see if we are there yet */
++ if (--fxo->battdebounce == 0) {
++ fxo->battery = BATTERY_LOST;
++ if (debug)
++ printk(KERN_DEBUG "NO BATTERY on %d/%d!\n", wc->span.spanno, card + 1);
++#ifdef JAPAN
++ if (!wc->ohdebounce && wc->offhook) {
++ dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_ONHOOK);
++ if (debug)
++ printk(KERN_DEBUG "Signalled On Hook\n");
++#ifdef ZERO_BATT_RING
++ wc->onhook++;
++#endif
++ }
++#else
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
++ /* set the alarm timer, taking into account that part of its time
++ period has already passed while debouncing occurred */
++ fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
++#endif
++ }
++ } else {
++ /* start the debounce timer to verify that battery has been lost */
++ fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
++ }
++ }
++ } else {
++ /* possible existing states:
++ battery lost or unknown, no debounce timer
++ battery lost or unknown, debounce timer (going to battery present)
++ battery present, no debounce timer
++ battery present, debounce timer (going to battery lost)
++ */
++
++ if (fxo->battery == BATTERY_PRESENT) {
++ if (fxo->battdebounce) {
++ /* we were going to BATTERY_LOST, but battery appeared again,
++ so clear the debounce timer */
++ fxo->battdebounce = 0;
++ }
++ } else {
++ if (fxo->battdebounce) {
++ /* going to BATTERY_PRESENT, see if we are there yet */
++ if (--fxo->battdebounce == 0) {
++ fxo->battery = BATTERY_PRESENT;
++ if (debug)
++ printk(KERN_DEBUG "BATTERY on %d/%d (%s)!\n", wc->span.spanno, card + 1,
++ (b < 0) ? "-" : "+");
++#ifdef ZERO_BATT_RING
++ if (wc->onhook) {
++ wc->onhook = 0;
++ dahdi_hooksig(&wc->chans[card], DAHDI_RXSIG_OFFHOOK);
++ if (debug)
++ printk(KERN_DEBUG "Signalled Off Hook\n");
++ }
++#else
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
++#endif
++ /* set the alarm timer, taking into account that part of its time
++ period has already passed while debouncing occurred */
++ fxo->battalarm = (battalarm - battdebounce) / MS_PER_CHECK_HOOK;
++ }
++ } else {
++ /* start the debounce timer to verify that battery has appeared */
++ fxo->battdebounce = battdebounce / MS_PER_CHECK_HOOK;
++ }
++ }
++ }
++
++ if (fxo->lastpol >= 0) {
++ if (b < 0) {
++ fxo->lastpol = -1;
++ fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
++ }
++ }
++ if (fxo->lastpol <= 0) {
++ if (b > 0) {
++ fxo->lastpol = 1;
++ fxo->polaritydebounce = POLARITY_DEBOUNCE / MS_PER_CHECK_HOOK;
++ }
++ }
++
++ if (fxo->battalarm) {
++ if (--fxo->battalarm == 0) {
++ /* the alarm timer has expired, so update the battery alarm state
++ for this channel */
++ dahdi_alarm_channel(wc->chans[card], fxo->battery == BATTERY_LOST ? DAHDI_ALARM_RED : DAHDI_ALARM_NONE);
++ }
++ }
++
++ if (fxo->polaritydebounce) {
++ if (--fxo->polaritydebounce == 0) {
++ if (fxo->lastpol != fxo->polarity) {
++ if (debug)
++ printk(KERN_DEBUG "%lu Polarity reversed (%d -> %d)\n", jiffies,
++ fxo->polarity,
++ fxo->lastpol);
++ if (fxo->polarity)
++ dahdi_qevent_lock(wc->chans[card], DAHDI_EVENT_POLARITY);
++ fxo->polarity = fxo->lastpol;
++ }
++ }
++ }
++#undef MS_PER_CHECK_HOOK
++}
++
++static inline void wctdm_proslic_check_hook(struct wctdm *wc, int card)
++{
++ char res;
++ int hook;
++
++ /* For some reason we have to debounce the
++ hook detector. */
++
++ res = wc->reg0shadow[card];
++ hook = (res & 1);
++ if (hook != wc->mod[card].fxs.lastrxhook) {
++ /* Reset the debounce (must be multiple of 4ms) */
++ wc->mod[card].fxs.debounce = dialdebounce * 4;
++
++#if 0
++ printk(KERN_DEBUG "Resetting debounce card %d hook %d, %d\n", card, hook, wc->mod[card].fxs.debounce);
++#endif
++ } else {
++ if (wc->mod[card].fxs.debounce > 0) {
++ wc->mod[card].fxs.debounce-= 16 * DAHDI_CHUNKSIZE;
++#if 0
++ printk(KERN_DEBUG "Sustaining hook %d, %d\n", hook, wc->mod[card].fxs.debounce);
++#endif
++ if (!wc->mod[card].fxs.debounce) {
++#if 0
++ printk(KERN_DEBUG "Counted down debounce, newhook: %d...\n", hook);
++#endif
++ wc->mod[card].fxs.debouncehook = hook;
++ }
++ if (!wc->mod[card].fxs.oldrxhook && wc->mod[card].fxs.debouncehook) {
++ /* Off hook */
++#if 1
++ if (debug)
++#endif
++ printk(KERN_DEBUG "opvxa1200: Card %d Going off hook\n", card);
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_OFFHOOK);
++ if (robust)
++ wctdm_init_proslic(wc, card, 1, 0, 1);
++ wc->mod[card].fxs.oldrxhook = 1;
++
++ } else if (wc->mod[card].fxs.oldrxhook && !wc->mod[card].fxs.debouncehook) {
++ /* On hook */
++#if 1
++ if (debug)
++#endif
++ printk(KERN_DEBUG "opvxa1200: Card %d Going on hook\n", card);
++ dahdi_hooksig(wc->chans[card], DAHDI_RXSIG_ONHOOK);
++ wc->mod[card].fxs.oldrxhook = 0;
++ }
++ }
++ }
++ wc->mod[card].fxs.lastrxhook = hook;
++}
++
++static irqreturn_t wctdm_interrupt(int irq, void *dev_id)
++{
++ struct wctdm *wc = dev_id;
++ unsigned char ints;
++ int x, y, z;
++ int mode;
++
++ ints = inb(wc->ioaddr + WC_INTSTAT);
++
++ if (!ints)
++ return IRQ_NONE;
++
++ outb(ints, wc->ioaddr + WC_INTSTAT);
++
++ if (ints & 0x10) {
++ /* Stop DMA, wait for watchdog */
++ printk(KERN_INFO "TDM PCI Master abort\n");
++ wctdm_stop_dma(wc);
++ return IRQ_RETVAL(1);
++ }
++
++ if (ints & 0x20) {
++ printk(KERN_INFO "PCI Target abort\n");
++ return IRQ_RETVAL(1);
++ }
++
++ for (x=0;x<wc->max_cards/*4*3*/;x++) {
++ if (wc->cardflag & (1 << x) &&
++ (wc->modtype[x] == MOD_TYPE_FXS)) {
++ if (wc->mod[x].fxs.lasttxhook == 0x4) {
++ /* RINGing, prepare for OHT */
++ wc->mod[x].fxs.ohttimer = OHT_TIMER << 3;
++ if (reversepolarity)
++ wc->mod[x].fxs.idletxhookstate = 0x6; /* OHT mode when idle */
++ else
++ wc->mod[x].fxs.idletxhookstate = 0x2;
++ } else {
++ if (wc->mod[x].fxs.ohttimer) {
++ wc->mod[x].fxs.ohttimer-= DAHDI_CHUNKSIZE;
++ if (!wc->mod[x].fxs.ohttimer) {
++ if (reversepolarity)
++ wc->mod[x].fxs.idletxhookstate = 0x5; /* Switch to active */
++ else
++ wc->mod[x].fxs.idletxhookstate = 0x1;
++ if ((wc->mod[x].fxs.lasttxhook == 0x2) || (wc->mod[x].fxs.lasttxhook == 0x6)) {
++ /* Apply the change if appropriate */
++ if (reversepolarity)
++ wc->mod[x].fxs.lasttxhook = 0x5;
++ else
++ wc->mod[x].fxs.lasttxhook = 0x1;
++ wctdm_setreg(wc, x, 64, wc->mod[x].fxs.lasttxhook);
++ }
++ }
++ }
++ }
++ }
++ }
++
++ if (ints & 0x0f) {
++ wc->intcount++;
++ z = wc->intcount & 0x3;
++ mode = wc->intcount & 0xc;
++ for(y=0; y<wc->max_cards/4/*3*/; y++)
++ {
++ x = z + y*4;
++ if (wc->cardflag & (1 << x ) )
++ {
++ switch(mode)
++ {
++ case 0:
++ /* Rest */
++ break;
++ case 4:
++ /* Read first shadow reg */
++ if (wc->modtype[x] == MOD_TYPE_FXS)
++ wc->reg0shadow[x] = wctdm_getreg(wc, x, 68);
++ else if (wc->modtype[x] == MOD_TYPE_FXO)
++ wc->reg0shadow[x] = wctdm_getreg(wc, x, 5);
++ break;
++ case 8:
++ /* Read second shadow reg */
++ if (wc->modtype[x] == MOD_TYPE_FXS)
++ wc->reg1shadow[x] = wctdm_getreg(wc, x, 64);
++ else if (wc->modtype[x] == MOD_TYPE_FXO)
++ wc->reg1shadow[x] = wctdm_getreg(wc, x, 29);
++ break;
++ case 12:
++ /* Perform processing */
++ if (wc->modtype[x] == MOD_TYPE_FXS) {
++ wctdm_proslic_check_hook(wc, x);
++ if (!(wc->intcount & 0xf0))
++ wctdm_proslic_recheck_sanity(wc, x);
++ } else if (wc->modtype[x] == MOD_TYPE_FXO) {
++ wctdm_voicedaa_check_hook(wc, x);
++ }
++ break;
++ }
++ }
++ }
++ if (!(wc->intcount % 10000)) {
++ /* Accept an alarm once per 10 seconds */
++ for (x=0;x<wc->max_cards/*4*3*/;x++)
++ if (wc->modtype[x] == MOD_TYPE_FXS) {
++ if (wc->mod[x].fxs.palarms)
++ wc->mod[x].fxs.palarms--;
++ }
++ }
++ wctdm_receiveprep(wc, ints);
++ wctdm_transmitprep(wc, ints);
++ }
++
++ return IRQ_RETVAL(1);
++
++}
++
++static int wctdm_voicedaa_insane(struct wctdm *wc, int card)
++{
++ int blah;
++ blah = wctdm_getreg(wc, card, 2);
++ if (blah != 0x3)
++ return -2;
++ blah = wctdm_getreg(wc, card, 11);
++ if (debug)
++ printk(KERN_DEBUG "VoiceDAA System: %02x\n", blah & 0xf);
++ return 0;
++}
++
++static int wctdm_proslic_insane(struct wctdm *wc, int card)
++{
++ int blah,insane_report;
++ insane_report=0;
++
++ blah = wctdm_getreg(wc, card, 0);
++ if (debug)
++ printk(KERN_DEBUG "ProSLIC on module %d, product %d, version %d\n", card, (blah & 0x30) >> 4, (blah & 0xf));
++
++#if 0
++ if ((blah & 0x30) >> 4) {
++ printk(KERN_DEBUG "ProSLIC on module %d is not a 3210.\n", card);
++ return -1;
++ }
++#endif
++ if (((blah & 0xf) == 0) || ((blah & 0xf) == 0xf)) {
++ /* SLIC not loaded */
++ return -1;
++ }
++ if ((blah & 0xf) < 2) {
++ printk(KERN_NOTICE "ProSLIC 3210 version %d is too old\n", blah & 0xf);
++ return -1;
++ }
++ if (wctdm_getreg(wc, card, 1) & 0x80)
++ /* ProSLIC 3215, not a 3210 */
++ wc->flags[card] |= FLAG_3215;
++
++ blah = wctdm_getreg(wc, card, 8);
++ if (blah != 0x2) {
++ printk(KERN_NOTICE "ProSLIC on module %d insane (1) %d should be 2\n", card, blah);
++ return -1;
++ } else if ( insane_report)
++ printk(KERN_NOTICE "ProSLIC on module %d Reg 8 Reads %d Expected is 0x2\n",card,blah);
++
++ blah = wctdm_getreg(wc, card, 64);
++ if (blah != 0x0) {
++ printk(KERN_NOTICE "ProSLIC on module %d insane (2)\n", card);
++ return -1;
++ } else if ( insane_report)
++ printk(KERN_NOTICE "ProSLIC on module %d Reg 64 Reads %d Expected is 0x0\n",card,blah);
++
++ blah = wctdm_getreg(wc, card, 11);
++ if (blah != 0x33) {
++ printk(KERN_NOTICE "ProSLIC on module %d insane (3)\n", card);
++ return -1;
++ } else if ( insane_report)
++ printk(KERN_NOTICE "ProSLIC on module %d Reg 11 Reads %d Expected is 0x33\n",card,blah);
++
++ /* Just be sure it's setup right. */
++ wctdm_setreg(wc, card, 30, 0);
++
++ if (debug)
++ printk(KERN_DEBUG "ProSLIC on module %d seems sane.\n", card);
++ return 0;
++}
++
++static int wctdm_proslic_powerleak_test(struct wctdm *wc, int card)
++{
++ unsigned long origjiffies;
++ unsigned char vbat;
++
++ /* Turn off linefeed */
++ wctdm_setreg(wc, card, 64, 0);
++
++ /* Power down */
++ wctdm_setreg(wc, card, 14, 0x10);
++
++ /* Wait for one second */
++ origjiffies = jiffies;
++
++ while((vbat = wctdm_getreg(wc, card, 82)) > 0x6) {
++ if ((jiffies - origjiffies) >= (HZ/2))
++ break;
++ }
++
++ if (vbat < 0x06) {
++ printk(KERN_NOTICE "Excessive leakage detected on module %d: %d volts (%02x) after %d ms\n", card,
++ 376 * vbat / 1000, vbat, (int)((jiffies - origjiffies) * 1000 / HZ));
++ return -1;
++ } else if (debug) {
++ printk(KERN_NOTICE "Post-leakage voltage: %d volts\n", 376 * vbat / 1000);
++ }
++ return 0;
++}
++
++static int wctdm_powerup_proslic(struct wctdm *wc, int card, int fast)
++{
++ unsigned char vbat;
++ unsigned long origjiffies;
++ int lim;
++
++ /* Set period of DC-DC converter to 1/64 khz */
++ wctdm_setreg(wc, card, 92, 0xff /* was 0xff */);
++
++ /* Wait for VBat to powerup */
++ origjiffies = jiffies;
++
++ /* Disable powerdown */
++ wctdm_setreg(wc, card, 14, 0);
++
++ /* If fast, don't bother checking anymore */
++ if (fast)
++ return 0;
++
++ while((vbat = wctdm_getreg(wc, card, 82)) < 0xc0) {
++ /* Wait no more than 500ms */
++ if ((jiffies - origjiffies) > HZ/2) {
++ break;
++ }
++ }
++
++ if (vbat < 0xc0) {
++ if (wc->proslic_power == PROSLIC_POWER_UNKNOWN)
++ printk(KERN_NOTICE "ProSLIC on module %d failed to powerup within %d ms (%d mV only)\n\n -- DID YOU REMEMBER TO PLUG IN THE HD POWER CABLE TO THE A1200P??\n",
++ card, (int)(((jiffies - origjiffies) * 1000 / HZ)),
++ vbat * 375);
++ wc->proslic_power = PROSLIC_POWER_WARNED;
++ return -1;
++ } else if (debug) {
++ printk(KERN_DEBUG "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
++ card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));
++ }
++ wc->proslic_power = PROSLIC_POWER_ON;
++
++ /* Proslic max allowed loop current, reg 71 LOOP_I_LIMIT */
++ /* If out of range, just set it to the default value */
++ lim = (loopcurrent - 20) / 3;
++ if ( loopcurrent > 41 ) {
++ lim = 0;
++ if (debug)
++ printk(KERN_DEBUG "Loop current out of range! Setting to default 20mA!\n");
++ }
++ else if (debug)
++ printk(KERN_DEBUG "Loop current set to %dmA!\n",(lim*3)+20);
++ wctdm_setreg(wc,card,LOOP_I_LIMIT,lim);
++
++ /* Engage DC-DC converter */
++ wctdm_setreg(wc, card, 93, 0x19 /* was 0x19 */);
++#if 0
++ origjiffies = jiffies;
++ while(0x80 & wctdm_getreg(wc, card, 93)) {
++ if ((jiffies - origjiffies) > 2 * HZ) {
++ printk(KERN_DEBUG "Timeout waiting for DC-DC calibration on module %d\n", card);
++ return -1;
++ }
++ }
++
++#if 0
++ /* Wait a full two seconds */
++ while((jiffies - origjiffies) < 2 * HZ);
++
++ /* Just check to be sure */
++ vbat = wctdm_getreg(wc, card, 82);
++ printk(KERN_DEBUG "ProSLIC on module %d powered up to -%d volts (%02x) in %d ms\n",
++ card, vbat * 376 / 1000, vbat, (int)(((jiffies - origjiffies) * 1000 / HZ)));
++#endif
++#endif
++ return 0;
++
++}
++
++static int wctdm_proslic_manual_calibrate(struct wctdm *wc, int card){
++ unsigned long origjiffies;
++ unsigned char i;
++
++ wctdm_setreg(wc, card, 21, 0);//(0) Disable all interupts in DR21
++ wctdm_setreg(wc, card, 22, 0);//(0)Disable all interupts in DR21
++ wctdm_setreg(wc, card, 23, 0);//(0)Disable all interupts in DR21
++ wctdm_setreg(wc, card, 64, 0);//(0)
++
++ wctdm_setreg(wc, card, 97, 0x18); //(0x18)Calibrations without the ADC and DAC offset and without common mode calibration.
++ wctdm_setreg(wc, card, 96, 0x47); //(0x47) Calibrate common mode and differential DAC mode DAC + ILIM
++
++ origjiffies=jiffies;
++ while( wctdm_getreg(wc,card,96)!=0 ){
++ if((jiffies-origjiffies)>80)
++ return -1;
++ }
++//Initialized DR 98 and 99 to get consistant results.
++// 98 and 99 are the results registers and the search should have same intial conditions.
++
++/*******************************The following is the manual gain mismatch calibration****************************/
++/*******************************This is also available as a function *******************************************/
++ // Delay 10ms
++ origjiffies=jiffies;
++ while((jiffies-origjiffies)<1);
++ wctdm_proslic_setreg_indirect(wc, card, 88,0);
++ wctdm_proslic_setreg_indirect(wc,card,89,0);
++ wctdm_proslic_setreg_indirect(wc,card,90,0);
++ wctdm_proslic_setreg_indirect(wc,card,91,0);
++ wctdm_proslic_setreg_indirect(wc,card,92,0);
++ wctdm_proslic_setreg_indirect(wc,card,93,0);
++
++ wctdm_setreg(wc, card, 98,0x10); // This is necessary if the calibration occurs other than at reset time
++ wctdm_setreg(wc, card, 99,0x10);
++
++ for ( i=0x1f; i>0; i--)
++ {
++ wctdm_setreg(wc, card, 98,i);
++ origjiffies=jiffies;
++ while((jiffies-origjiffies)<4);
++ if((wctdm_getreg(wc,card,88)) == 0)
++ break;
++ } // for
++
++ for ( i=0x1f; i>0; i--)
++ {
++ wctdm_setreg(wc, card, 99,i);
++ origjiffies=jiffies;
++ while((jiffies-origjiffies)<4);
++ if((wctdm_getreg(wc,card,89)) == 0)
++ break;
++ }//for
++
++/*******************************The preceding is the manual gain mismatch calibration****************************/
++/**********************************The following is the longitudinal Balance Cal***********************************/
++ wctdm_setreg(wc,card,64,1);
++ while((jiffies-origjiffies)<10); // Sleep 100?
++
++ wctdm_setreg(wc, card, 64, 0);
++ wctdm_setreg(wc, card, 23, 0x4); // enable interrupt for the balance Cal
++ wctdm_setreg(wc, card, 97, 0x1); // this is a singular calibration bit for longitudinal calibration
++ wctdm_setreg(wc, card, 96,0x40);
++
++ wctdm_getreg(wc,card,96); /* Read Reg 96 just cause */
++
++ wctdm_setreg(wc, card, 21, 0xFF);
++ wctdm_setreg(wc, card, 22, 0xFF);
++ wctdm_setreg(wc, card, 23, 0xFF);
++
++ /**The preceding is the longitudinal Balance Cal***/
++ return(0);
++
++}
++#if 1
++static int wctdm_proslic_calibrate(struct wctdm *wc, int card)
++{
++ unsigned long origjiffies;
++ int x;
++ /* Perform all calibrations */
++ wctdm_setreg(wc, card, 97, 0x1f);
++
++ /* Begin, no speedup */
++ wctdm_setreg(wc, card, 96, 0x5f);
++
++ /* Wait for it to finish */
++ origjiffies = jiffies;
++ while(wctdm_getreg(wc, card, 96)) {
++ if ((jiffies - origjiffies) > 2 * HZ) {
++ printk(KERN_NOTICE "Timeout waiting for calibration of module %d\n", card);
++ return -1;
++ }
++ }
++
++ if (debug) {
++ /* Print calibration parameters */
++ printk(KERN_DEBUG "Calibration Vector Regs 98 - 107: \n");
++ for (x=98;x<108;x++) {
++ printk(KERN_DEBUG "%d: %02x\n", x, wctdm_getreg(wc, card, x));
++ }
++ }
++ return 0;
++}
++#endif
++
++static void wait_just_a_bit(int foo)
++{
++ long newjiffies;
++ newjiffies = jiffies + foo;
++ while(jiffies < newjiffies);
++}
++
++/*********************************************************************
++ * Set the hwgain on the analog modules
++ *
++ * card = the card position for this module (0-23)
++ * gain = gain in dB x10 (e.g. -3.5dB would be gain=-35)
++ * tx = (0 for rx; 1 for tx)
++ *
++ *******************************************************************/
++static int wctdm_set_hwgain(struct wctdm *wc, int card, __s32 gain, __u32 tx)
++{
++ if (!(wc->modtype[card] == MOD_TYPE_FXO)) {
++ printk(KERN_NOTICE "Cannot adjust gain. Unsupported module type!\n");
++ return -1;
++ }
++ if (tx) {
++ if (debug)
++ printk(KERN_DEBUG "setting FXO tx gain for card=%d to %d\n", card, gain);
++ if (gain >= -150 && gain <= 0) {
++ wctdm_setreg(wc, card, 38, 16 + (gain/-10));
++ wctdm_setreg(wc, card, 40, 16 + (-gain%10));
++ } else if (gain <= 120 && gain > 0) {
++ wctdm_setreg(wc, card, 38, gain/10);
++ wctdm_setreg(wc, card, 40, (gain%10));
++ } else {
++ printk(KERN_INFO "FXO tx gain is out of range (%d)\n", gain);
++ return -1;
++ }
++ } else { /* rx */
++ if (debug)
++ printk(KERN_DEBUG "setting FXO rx gain for card=%d to %d\n", card, gain);
++ if (gain >= -150 && gain <= 0) {
++ wctdm_setreg(wc, card, 39, 16+ (gain/-10));
++ wctdm_setreg(wc, card, 41, 16 + (-gain%10));
++ } else if (gain <= 120 && gain > 0) {
++ wctdm_setreg(wc, card, 39, gain/10);
++ wctdm_setreg(wc, card, 41, (gain%10));
++ } else {
++ printk(KERN_INFO "FXO rx gain is out of range (%d)\n", gain);
++ return -1;
++ }
++ }
++
++ return 0;
++}
++
++static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual, int sane)
++{
++ unsigned char reg16=0, reg26=0, reg30=0, reg31=0;
++ long newjiffies;
++ wc->modtype[card] = MOD_TYPE_FXO;
++ /* Sanity check the ProSLIC */
++ reset_spi(wc, card);
++ if (!sane && wctdm_voicedaa_insane(wc, card))
++ return -2;
++
++ /* Software reset */
++ wctdm_setreg(wc, card, 1, 0x80);
++
++ /* Wait just a bit */
++ wait_just_a_bit(HZ/10);
++
++ /* Enable PCM, ulaw */
++ if (alawoverride)
++ wctdm_setreg(wc, card, 33, 0x20);
++ else
++ wctdm_setreg(wc, card, 33, 0x28);
++
++ /* Set On-hook speed, Ringer impedence, and ringer threshold */
++ reg16 |= (fxo_modes[_opermode].ohs << 6);
++ reg16 |= (fxo_modes[_opermode].rz << 1);
++ reg16 |= (fxo_modes[_opermode].rt);
++ wctdm_setreg(wc, card, 16, reg16);
++
++ if(fwringdetect) {
++ /* Enable ring detector full-wave rectifier mode */
++ wctdm_setreg(wc, card, 18, 2);
++ wctdm_setreg(wc, card, 24, 0);
++ } else {
++ /* Set to the device defaults */
++ wctdm_setreg(wc, card, 18, 0);
++ wctdm_setreg(wc, card, 24, 0x19);
++ }
++
++ /* Set DC Termination:
++ Tip/Ring voltage adjust, minimum operational current, current limitation */
++ reg26 |= (fxo_modes[_opermode].dcv << 6);
++ reg26 |= (fxo_modes[_opermode].mini << 4);
++ reg26 |= (fxo_modes[_opermode].ilim << 1);
++ wctdm_setreg(wc, card, 26, reg26);
++
++ /* Set AC Impedence */
++ reg30 = (fxofullscale==1) ? (fxo_modes[_opermode].acim|0x10) : (fxo_modes[_opermode].acim);
++ wctdm_setreg(wc, card, 30, reg30);
++
++ /* Misc. DAA parameters */
++ if (fastpickup)
++ reg31 = 0xb3;
++ else
++ reg31 = 0xa3;
++
++ reg31 |= (fxo_modes[_opermode].ohs2 << 3);
++ wctdm_setreg(wc, card, 31, reg31);
++
++ /* Set Transmit/Receive timeslot */
++ //printk("set card %d to %d\n", card, (3-(card%4)) * 8 + (card/4) * 64);
++ wctdm_setreg(wc, card, 34, (3-(card%4)) * 8 + (card/4) * 64);
++ wctdm_setreg(wc, card, 35, 0x00);
++ wctdm_setreg(wc, card, 36, (3-(card%4)) * 8 + (card/4) * 64);
++ wctdm_setreg(wc, card, 37, 0x00);
++
++ /* Enable ISO-Cap */
++ wctdm_setreg(wc, card, 6, 0x00);
++
++ if (fastpickup)
++ wctdm_setreg(wc, card, 17, wctdm_getreg(wc, card, 17) | 0x20);
++
++ /* Wait 1000ms for ISO-cap to come up */
++ newjiffies = jiffies;
++ newjiffies += 2 * HZ;
++ while((jiffies < newjiffies) && !(wctdm_getreg(wc, card, 11) & 0xf0))
++ wait_just_a_bit(HZ/10);
++
++ if (!(wctdm_getreg(wc, card, 11) & 0xf0)) {
++ printk(KERN_NOTICE "VoiceDAA did not bring up ISO link properly!\n");
++ return -1;
++ }
++ if (debug)
++ printk(KERN_DEBUG "ISO-Cap is now up, line side: %02x rev %02x\n",
++ wctdm_getreg(wc, card, 11) >> 4,
++ (wctdm_getreg(wc, card, 13) >> 2) & 0xf);
++ /* Enable on-hook line monitor */
++ wctdm_setreg(wc, card, 5, 0x08);
++
++ /* Take values for fxotxgain and fxorxgain and apply them to module */
++ wctdm_set_hwgain(wc, card, fxotxgain, 1);
++ wctdm_set_hwgain(wc, card, fxorxgain, 0);
++
++ /* NZ -- crank the tx gain up by 7 dB */
++ if (!strcmp(fxo_modes[_opermode].name, "NEWZEALAND")) {
++ printk(KERN_INFO "Adjusting gain\n");
++ wctdm_set_hwgain(wc, card, 7, 1);
++ }
++
++ if(debug)
++ printk(KERN_DEBUG "DEBUG fxotxgain:%i.%i fxorxgain:%i.%i\n", (wctdm_getreg(wc, card, 38)/16)?-(wctdm_getreg(wc, card, 38) - 16) : wctdm_getreg(wc, card, 38), (wctdm_getreg(wc, card, 40)/16)? -(wctdm_getreg(wc, card, 40) - 16):wctdm_getreg(wc, card, 40), (wctdm_getreg(wc, card, 39)/16)? -(wctdm_getreg(wc, card, 39) - 16) : wctdm_getreg(wc, card, 39),(wctdm_getreg(wc, card, 41)/16)?-(wctdm_getreg(wc, card, 41) - 16):wctdm_getreg(wc, card, 41));
++
++ return 0;
++
++}
++
++static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual, int sane)
++{
++
++ unsigned short tmp[5];
++ unsigned char r19, r9;
++ int x;
++ int fxsmode=0;
++
++ /* Sanity check the ProSLIC */
++ if (!sane && wctdm_proslic_insane(wc, card))
++ return -2;
++
++ /* By default, don't send on hook */
++ if (reversepolarity)
++ wc->mod[card].fxs.idletxhookstate = 5;
++ else
++ wc->mod[card].fxs.idletxhookstate = 1;
++
++ if (sane) {
++ /* Make sure we turn off the DC->DC converter to prevent anything from blowing up */
++ wctdm_setreg(wc, card, 14, 0x10);
++ }
++
++ if (wctdm_proslic_init_indirect_regs(wc, card)) {
++ printk(KERN_INFO "Indirect Registers failed to initialize on module %d.\n", card);
++ return -1;
++ }
++
++ /* Clear scratch pad area */
++ wctdm_proslic_setreg_indirect(wc, card, 97,0);
++
++ /* Clear digital loopback */
++ wctdm_setreg(wc, card, 8, 0);
++
++ /* Revision C optimization */
++ wctdm_setreg(wc, card, 108, 0xeb);
++
++ /* Disable automatic VBat switching for safety to prevent
++ Q7 from accidently turning on and burning out. */
++ wctdm_setreg(wc, card, 67, 0x07); /* Note, if pulse dialing has problems at high REN loads
++ change this to 0x17 */
++
++ /* Turn off Q7 */
++ wctdm_setreg(wc, card, 66, 1);
++
++ /* Flush ProSLIC digital filters by setting to clear, while
++ saving old values */
++ for (x=0;x<5;x++) {
++ tmp[x] = wctdm_proslic_getreg_indirect(wc, card, x + 35);
++ wctdm_proslic_setreg_indirect(wc, card, x + 35, 0x8000);
++ }
++
++ /* Power up the DC-DC converter */
++ if (wctdm_powerup_proslic(wc, card, fast)) {
++ printk(KERN_NOTICE "Unable to do INITIAL ProSLIC powerup on module %d\n", card);
++ return -1;
++ }
++
++ if (!fast) {
++
++ /* Check for power leaks */
++ if (wctdm_proslic_powerleak_test(wc, card)) {
++ printk(KERN_NOTICE "ProSLIC module %d failed leakage test. Check for short circuit\n", card);
++ }
++ /* Power up again */
++ if (wctdm_powerup_proslic(wc, card, fast)) {
++ printk(KERN_NOTICE "Unable to do FINAL ProSLIC powerup on module %d\n", card);
++ return -1;
++ }
++#ifndef NO_CALIBRATION
++ /* Perform calibration */
++ if(manual) {
++ if (wctdm_proslic_manual_calibrate(wc, card)) {
++ //printk(KERN_NOTICE "Proslic failed on Manual Calibration\n");
++ if (wctdm_proslic_manual_calibrate(wc, card)) {
++ printk(KERN_NOTICE "Proslic Failed on Second Attempt to Calibrate Manually. (Try -DNO_CALIBRATION in Makefile)\n");
++ return -1;
++ }
++ printk(KERN_NOTICE "Proslic Passed Manual Calibration on Second Attempt\n");
++ }
++ }
++ else {
++ if(wctdm_proslic_calibrate(wc, card)) {
++ //printk(KERN_NOTICE "ProSlic died on Auto Calibration.\n");
++ if (wctdm_proslic_calibrate(wc, card)) {
++ printk(KERN_NOTICE "Proslic Failed on Second Attempt to Auto Calibrate\n");
++ return -1;
++ }
++ printk(KERN_NOTICE "Proslic Passed Auto Calibration on Second Attempt\n");
++ }
++ }
++ /* Perform DC-DC calibration */
++ wctdm_setreg(wc, card, 93, 0x99);
++ r19 = wctdm_getreg(wc, card, 107);
++ if ((r19 < 0x2) || (r19 > 0xd)) {
++ printk(KERN_NOTICE "DC-DC cal has a surprising direct 107 of 0x%02x!\n", r19);
++ wctdm_setreg(wc, card, 107, 0x8);
++ }
++
++ /* Save calibration vectors */
++ for (x=0;x<NUM_CAL_REGS;x++)
++ wc->mod[card].fxs.calregs.vals[x] = wctdm_getreg(wc, card, 96 + x);
++#endif
++
++ } else {
++ /* Restore calibration registers */
++ for (x=0;x<NUM_CAL_REGS;x++)
++ wctdm_setreg(wc, card, 96 + x, wc->mod[card].fxs.calregs.vals[x]);
++ }
++ /* Calibration complete, restore original values */
++ for (x=0;x<5;x++) {
++ wctdm_proslic_setreg_indirect(wc, card, x + 35, tmp[x]);
++ }
++
++ if (wctdm_proslic_verify_indirect_regs(wc, card)) {
++ printk(KERN_INFO "Indirect Registers failed verification.\n");
++ return -1;
++ }
++
++
++#if 0
++ /* Disable Auto Power Alarm Detect and other "features" */
++ wctdm_setreg(wc, card, 67, 0x0e);
++ blah = wctdm_getreg(wc, card, 67);
++#endif
++
++#if 0
++ if (wctdm_proslic_setreg_indirect(wc, card, 97, 0x0)) { // Stanley: for the bad recording fix
++ printk(KERN_INFO "ProSlic IndirectReg Died.\n");
++ return -1;
++ }
++#endif
++
++ if (alawoverride)
++ wctdm_setreg(wc, card, 1, 0x20);
++ else
++ wctdm_setreg(wc, card, 1, 0x28);
++ // U-Law 8-bit interface
++ wctdm_setreg(wc, card, 2, (3-(card%4)) * 8 + (card/4) * 64); // Tx Start count low byte 0
++ wctdm_setreg(wc, card, 3, 0); // Tx Start count high byte 0
++ wctdm_setreg(wc, card, 4, (3-(card%4)) * 8 + (card/4) * 64); // Rx Start count low byte 0
++ wctdm_setreg(wc, card, 5, 0); // Rx Start count high byte 0
++ wctdm_setreg(wc, card, 18, 0xff); // clear all interrupt
++ wctdm_setreg(wc, card, 19, 0xff);
++ wctdm_setreg(wc, card, 20, 0xff);
++ wctdm_setreg(wc, card, 73, 0x04);
++ if (fxshonormode) {
++ fxsmode = acim2tiss[fxo_modes[_opermode].acim];
++ wctdm_setreg(wc, card, 10, 0x08 | fxsmode);
++ if (fxo_modes[_opermode].ring_osc)
++ wctdm_proslic_setreg_indirect(wc, card, 20, fxo_modes[_opermode].ring_osc);
++ if (fxo_modes[_opermode].ring_x)
++ wctdm_proslic_setreg_indirect(wc, card, 21, fxo_modes[_opermode].ring_x);
++ }
++ if (lowpower)
++ wctdm_setreg(wc, card, 72, 0x10);
++
++#if 0
++ wctdm_setreg(wc, card, 21, 0x00); // enable interrupt
++ wctdm_setreg(wc, card, 22, 0x02); // Loop detection interrupt
++ wctdm_setreg(wc, card, 23, 0x01); // DTMF detection interrupt
++#endif
++
++#if 0
++ /* Enable loopback */
++ wctdm_setreg(wc, card, 8, 0x2);
++ wctdm_setreg(wc, card, 14, 0x0);
++ wctdm_setreg(wc, card, 64, 0x0);
++ wctdm_setreg(wc, card, 1, 0x08);
++#endif
++
++ if (fastringer) {
++ /* Speed up Ringer */
++ wctdm_proslic_setreg_indirect(wc, card, 20, 0x7e6d);
++ wctdm_proslic_setreg_indirect(wc, card, 21, 0x01b9);
++ /* Beef up Ringing voltage to 89V */
++ if (boostringer) {
++ wctdm_setreg(wc, card, 74, 0x3f);
++ if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x247))
++ return -1;
++ printk(KERN_INFO "Boosting fast ringer on slot %d (89V peak)\n", card + 1);
++ } else if (lowpower) {
++ if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x14b))
++ return -1;
++ printk(KERN_INFO "Reducing fast ring power on slot %d (50V peak)\n", card + 1);
++ } else
++ printk(KERN_INFO "Speeding up ringer on slot %d (25Hz)\n", card + 1);
++ } else {
++ /* Beef up Ringing voltage to 89V */
++ if (boostringer) {
++ wctdm_setreg(wc, card, 74, 0x3f);
++ if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x1d1))
++ return -1;
++ printk(KERN_INFO "Boosting ringer on slot %d (89V peak)\n", card + 1);
++ } else if (lowpower) {
++ if (wctdm_proslic_setreg_indirect(wc, card, 21, 0x108))
++ return -1;
++ printk(KERN_INFO "Reducing ring power on slot %d (50V peak)\n", card + 1);
++ }
++ }
++
++ if(fxstxgain || fxsrxgain) {
++ r9 = wctdm_getreg(wc, card, 9);
++ switch (fxstxgain) {
++
++ case 35:
++ r9+=8;
++ break;
++ case -35:
++ r9+=4;
++ break;
++ case 0:
++ break;
++ }
++
++ switch (fxsrxgain) {
++
++ case 35:
++ r9+=2;
++ break;
++ case -35:
++ r9+=1;
++ break;
++ case 0:
++ break;
++ }
++ wctdm_setreg(wc,card,9,r9);
++ }
++
++ if(debug)
++ printk(KERN_DEBUG "DEBUG: fxstxgain:%s fxsrxgain:%s\n",((wctdm_getreg(wc, card, 9)/8) == 1)?"3.5":(((wctdm_getreg(wc,card,9)/4) == 1)?"-3.5":"0.0"),((wctdm_getreg(wc, card, 9)/2) == 1)?"3.5":((wctdm_getreg(wc,card,9)%2)?"-3.5":"0.0"));
++
++ wctdm_setreg(wc, card, 64, 0x01);
++ return 0;
++}
++
++
++static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
++{
++ struct wctdm_stats stats;
++ struct wctdm_regs regs;
++ struct wctdm_regop regop;
++ struct wctdm_echo_coefs echoregs;
++ struct dahdi_hwgain hwgain;
++ struct wctdm *wc = chan->pvt;
++ int x;
++ switch (cmd) {
++ case DAHDI_ONHOOKTRANSFER:
++ if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
++ return -EINVAL;
++ if (get_user(x, (__user int *)data))
++ return -EFAULT;
++ wc->mod[chan->chanpos - 1].fxs.ohttimer = x << 3;
++ if (reversepolarity)
++ wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 0x6; /* OHT mode when idle */
++ else
++ wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 0x2;
++ if (wc->mod[chan->chanpos - 1].fxs.lasttxhook == 0x1 || wc->mod[chan->chanpos - 1].fxs.lasttxhook == 0x5) {
++ /* Apply the change if appropriate */
++ if (reversepolarity)
++ wc->mod[chan->chanpos - 1].fxs.lasttxhook = 0x6;
++ else
++ wc->mod[chan->chanpos - 1].fxs.lasttxhook = 0x2;
++ wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
++ }
++ break;
++ case DAHDI_SETPOLARITY:
++ if (get_user(x, (__user int *)data))
++ return -EFAULT;
++ if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
++ return -EINVAL;
++ /* Can't change polarity while ringing or when open */
++ if ((wc->mod[chan->chanpos -1 ].fxs.lasttxhook == 0x04) ||
++ (wc->mod[chan->chanpos -1 ].fxs.lasttxhook == 0x00))
++ return -EINVAL;
++
++ if ((x && !reversepolarity) || (!x && reversepolarity))
++ wc->mod[chan->chanpos - 1].fxs.lasttxhook |= 0x04;
++ else
++ wc->mod[chan->chanpos - 1].fxs.lasttxhook &= ~0x04;
++ wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
++ break;
++ case WCTDM_GET_STATS:
++ if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
++ stats.tipvolt = wctdm_getreg(wc, chan->chanpos - 1, 80) * -376;
++ stats.ringvolt = wctdm_getreg(wc, chan->chanpos - 1, 81) * -376;
++ stats.batvolt = wctdm_getreg(wc, chan->chanpos - 1, 82) * -376;
++ } else if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
++ stats.tipvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
++ stats.ringvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
++ stats.batvolt = (signed char)wctdm_getreg(wc, chan->chanpos - 1, 29) * 1000;
++ } else
++ return -EINVAL;
++ if (copy_to_user((__user void *)data, &stats, sizeof(stats)))
++ return -EFAULT;
++ break;
++ case WCTDM_GET_REGS:
++ if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
++ for (x=0;x<NUM_INDIRECT_REGS;x++)
++ regs.indirect[x] = wctdm_proslic_getreg_indirect(wc, chan->chanpos -1, x);
++ for (x=0;x<NUM_REGS;x++)
++ regs.direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x);
++ } else {
++ memset(&regs, 0, sizeof(regs));
++ for (x=0;x<NUM_FXO_REGS;x++)
++ regs.direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x);
++ }
++ if (copy_to_user((__user void *)data, &regs, sizeof(regs)))
++ return -EFAULT;
++ break;
++ case WCTDM_SET_REG:
++ if (copy_from_user(&regop, (__user void *)data, sizeof(regop)))
++ return -EFAULT;
++ if (regop.indirect) {
++ if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
++ return -EINVAL;
++ printk(KERN_INFO "Setting indirect %d to 0x%04x on %d\n", regop.reg, regop.val, chan->chanpos);
++ wctdm_proslic_setreg_indirect(wc, chan->chanpos - 1, regop.reg, regop.val);
++ } else {
++ regop.val &= 0xff;
++ printk(KERN_INFO "Setting direct %d to %04x on %d\n", regop.reg, regop.val, chan->chanpos);
++ wctdm_setreg(wc, chan->chanpos - 1, regop.reg, regop.val);
++ }
++ break;
++ case WCTDM_SET_ECHOTUNE:
++ printk(KERN_INFO "-- Setting echo registers: \n");
++ if (copy_from_user(&echoregs, (__user void *)data, sizeof(echoregs)))
++ return -EFAULT;
++
++ if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
++ /* Set the ACIM register */
++ wctdm_setreg(wc, chan->chanpos - 1, 30, (fxofullscale==1) ? (echoregs.acim|0x10) : echoregs.acim);
++
++ /* Set the digital echo canceller registers */
++ wctdm_setreg(wc, chan->chanpos - 1, 45, echoregs.coef1);
++ wctdm_setreg(wc, chan->chanpos - 1, 46, echoregs.coef2);
++ wctdm_setreg(wc, chan->chanpos - 1, 47, echoregs.coef3);
++ wctdm_setreg(wc, chan->chanpos - 1, 48, echoregs.coef4);
++ wctdm_setreg(wc, chan->chanpos - 1, 49, echoregs.coef5);
++ wctdm_setreg(wc, chan->chanpos - 1, 50, echoregs.coef6);
++ wctdm_setreg(wc, chan->chanpos - 1, 51, echoregs.coef7);
++ wctdm_setreg(wc, chan->chanpos - 1, 52, echoregs.coef8);
++
++ printk(KERN_INFO "-- Set echo registers successfully\n");
++
++ break;
++ } else {
++ return -EINVAL;
++
++ }
++ break;
++ case DAHDI_SET_HWGAIN:
++ if (copy_from_user(&hwgain, (__user void *) data, sizeof(hwgain)))
++ return -EFAULT;
++
++ wctdm_set_hwgain(wc, chan->chanpos-1, hwgain.newgain, hwgain.tx);
++
++ if (debug)
++ printk(KERN_DEBUG "Setting hwgain on channel %d to %d for %s direction\n",
++ chan->chanpos-1, hwgain.newgain, hwgain.tx ? "tx" : "rx");
++ break;
++ default:
++ return -ENOTTY;
++ }
++ return 0;
++
++}
++
++static int wctdm_open(struct dahdi_chan *chan)
++{
++ struct wctdm *wc = chan->pvt;
++ if (!(wc->cardflag & (1 << (chan->chanpos - 1))))
++ return -ENODEV;
++ if (wc->dead)
++ return -ENODEV;
++ wc->usecount++;
++
++ /*MOD_INC_USE_COUNT; */
++ try_module_get(THIS_MODULE);
++ return 0;
++}
++
++static inline struct wctdm *wctdm_from_span(struct dahdi_span *span)
++{
++ return container_of(span, struct wctdm, span);
++}
++
++static int wctdm_watchdog(struct dahdi_span *span, int event)
++{
++ printk(KERN_INFO "opvxa1200: Restarting DMA\n");
++ wctdm_restart_dma(wctdm_from_span(span));
++ return 0;
++}
++
++static int wctdm_close(struct dahdi_chan *chan)
++{
++ struct wctdm *wc = chan->pvt;
++ wc->usecount--;
++
++ /*MOD_DEC_USE_COUNT;*/
++ module_put(THIS_MODULE);
++
++ if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
++ if (reversepolarity)
++ wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 5;
++ else
++ wc->mod[chan->chanpos - 1].fxs.idletxhookstate = 1;
++ }
++ /* If we're dead, release us now */
++ if (!wc->usecount && wc->dead)
++ wctdm_release(wc);
++ return 0;
++}
++
++static int wctdm_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
++{
++ struct wctdm *wc = chan->pvt;
++ int reg=0;
++ if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXO) {
++ /* XXX Enable hooksig for FXO XXX */
++ switch(txsig) {
++ case DAHDI_TXSIG_START:
++ case DAHDI_TXSIG_OFFHOOK:
++ wc->mod[chan->chanpos - 1].fxo.offhook = 1;
++ wctdm_setreg(wc, chan->chanpos - 1, 5, 0x9);
++ if(cidbeforering)
++ {
++ wc->cid_state[chan->chanpos - 1] = CID_STATE_IDLE;
++ wc->cid_history_clone_cnt[chan->chanpos - 1] = 0;
++ wc->cid_history_ptr[chan->chanpos - 1] = 0;
++ memset(wc->cid_history_buf[chan->chanpos - 1], DAHDI_LIN2X(0, chan), cidbuflen * DAHDI_MAX_CHUNKSIZE);
++ }
++ break;
++ case DAHDI_TXSIG_ONHOOK:
++ wc->mod[chan->chanpos - 1].fxo.offhook = 0;
++ wctdm_setreg(wc, chan->chanpos - 1, 5, 0x8);
++ break;
++ default:
++ printk(KERN_NOTICE "wcfxo: Can't set tx state to %d\n", txsig);
++ }
++ } else {
++ switch(txsig) {
++ case DAHDI_TXSIG_ONHOOK:
++ switch(chan->sig) {
++ case DAHDI_SIG_EM:
++ case DAHDI_SIG_FXOKS:
++ case DAHDI_SIG_FXOLS:
++ wc->mod[chan->chanpos-1].fxs.lasttxhook = wc->mod[chan->chanpos-1].fxs.idletxhookstate;
++ break;
++ case DAHDI_SIG_FXOGS:
++ wc->mod[chan->chanpos-1].fxs.lasttxhook = 3;
++ break;
++ }
++ break;
++ case DAHDI_TXSIG_OFFHOOK:
++ switch(chan->sig) {
++ case DAHDI_SIG_EM:
++ wc->mod[chan->chanpos-1].fxs.lasttxhook = 5;
++ break;
++ default:
++ wc->mod[chan->chanpos-1].fxs.lasttxhook = wc->mod[chan->chanpos-1].fxs.idletxhookstate;
++ break;
++ }
++ break;
++ case DAHDI_TXSIG_START:
++ wc->mod[chan->chanpos-1].fxs.lasttxhook = 4;
++ break;
++ case DAHDI_TXSIG_KEWL:
++ wc->mod[chan->chanpos-1].fxs.lasttxhook = 0;
++ break;
++ default:
++ printk(KERN_NOTICE "opvxa1200: Can't set tx state to %d\n", txsig);
++ }
++ if (debug)
++ printk(KERN_DEBUG "Setting FXS hook state to %d (%02x)\n", txsig, reg);
++
++#if 1
++ wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos-1].fxs.lasttxhook);
++#endif
++ }
++ return 0;
++}
++
++#ifdef DAHDI_SPAN_OPS
++static const struct dahdi_span_ops wctdm_span_ops = {
++ .owner = THIS_MODULE,
++ .hooksig = wctdm_hooksig,
++ .open = wctdm_open,
++ .close = wctdm_close,
++ .ioctl = wctdm_ioctl,
++ .watchdog = wctdm_watchdog,
++};
++#endif
++
++static int wctdm_initialize(struct wctdm *wc)
++{
++ int x;
++
++ /* Dahdi stuff */
++ sprintf(wc->span.name, "OPVXA1200/%d", wc->pos);
++ snprintf(wc->span.desc, sizeof(wc->span.desc)-1, "%s Board %d", wc->variety, wc->pos + 1);
++ wc->ddev->location = kasprintf(GFP_KERNEL,
++ "PCI Bus %02d Slot %02d",
++ wc->dev->bus->number,
++ PCI_SLOT(wc->dev->devfn) + 1);
++ if (!wc->ddev->location) {
++ dahdi_free_device(wc->ddev);
++ wc->ddev = NULL;
++ return -ENOMEM;
++ }
++ wc->ddev->manufacturer = "OpenVox";
++ wc->ddev->devicetype = wc->variety;
++ if (alawoverride) {
++ printk(KERN_INFO "ALAW override parameter detected. Device will be operating in ALAW\n");
++ wc->span.deflaw = DAHDI_LAW_ALAW;
++ } else
++ wc->span.deflaw = DAHDI_LAW_MULAW;
++
++ x = __wctdm_getcreg(wc, WC_VER);
++ wc->fwversion = x;
++ if( x & FLAG_A800)
++ {
++ wc->card_name = A800P_Name;
++ wc->max_cards = 8;
++ }
++ else
++ {
++ wc->card_name = A1200P_Name;
++ wc->max_cards = 12;
++ }
++
++ for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
++ sprintf(wc->chans[x]->name, "OPVXA1200/%d/%d", wc->pos, x);
++ wc->chans[x]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR;
++ wc->chans[x]->sigcap |= DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
++ wc->chans[x]->chanpos = x+1;
++ wc->chans[x]->pvt = wc;
++ }
++
++#ifdef DAHDI_SPAN_MODULE
++ wc->span.owner = THIS_MODULE;
++#endif
++
++#ifdef DAHDI_SPAN_OPS
++ wc->span.ops = &wctdm_span_ops;
++#else
++ wc->span.hooksig = wctdm_hooksig,
++ wc->span.watchdog = wctdm_watchdog,
++ wc->span.open = wctdm_open;
++ wc->span.close = wctdm_close;
++ wc->span.ioctl = wctdm_ioctl;
++ wc->span.pvt = wc;
++#endif
++ wc->span.chans = wc->chans;
++ wc->span.channels = wc->max_cards; /*MAX_NUM_CARDS;*/
++ wc->span.flags = DAHDI_FLAG_RBS;
++ wc->span.ops = &wctdm_span_ops;
++
++ list_add_tail(&wc->span.device_node, &wc->ddev->spans);
++ if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
++ printk(KERN_NOTICE "Unable to register device %s with DAHDI\n",
++ wc->span.name);
++ kfree(wc->ddev->location);
++ dahdi_free_device(wc->ddev);
++ wc->ddev = NULL;
++ return -1;
++ }
++ return 0;
++}
++
++static void wctdm_post_initialize(struct wctdm *wc)
++{
++ int x;
++
++ /* Finalize signalling */
++ for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
++ if (wc->cardflag & (1 << x)) {
++ if (wc->modtype[x] == MOD_TYPE_FXO)
++ wc->chans[x]->sigcap = DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF | DAHDI_SIG_CLEAR;
++ else
++ wc->chans[x]->sigcap = DAHDI_SIG_FXOKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_SF | DAHDI_SIG_EM | DAHDI_SIG_CLEAR;
++ } else if (!(wc->chans[x]->sigcap & DAHDI_SIG_BROKEN)) {
++ wc->chans[x]->sigcap = 0;
++ }
++ }
++}
++
++static int wctdm_hardware_init(struct wctdm *wc)
++{
++ /* Hardware stuff */
++ unsigned char ver;
++ unsigned char x,y;
++ int failed;
++ long origjiffies; //ml.
++
++ /* Signal Reset */
++ printk("before raise reset\n");
++ outb(0x01, wc->ioaddr + WC_CNTL);
++
++ /* Wait for 5 second */
++
++ origjiffies = jiffies;
++
++ while(1)
++ {
++ if ((jiffies - origjiffies) >= (HZ*5))
++ break;;
++ }
++
++ /* printk(KERN_INFO "after raise reset\n");*/
++
++ /* Check OpenVox chip */
++ x=inb(wc->ioaddr + WC_CNTL);
++ ver = __wctdm_getcreg(wc, WC_VER);
++ wc->fwversion = ver;
++ /*if( ver & FLAG_A800)
++ {
++ wc->card_name = A800P_Name;
++ wc->max_cards = 8;
++ }
++ else
++ {
++ wc->card_name = A1200P_Name;
++ wc->max_cards = 12;
++ }*/
++ printk(KERN_NOTICE "OpenVox %s version: %01x.%01x\n", wc->card_name, (ver&(~FLAG_A800))>>4, ver&0x0f);
++
++ failed = 0;
++ if (ver != 0x00) {
++ for (x=0;x<16;x++) {
++ /* Test registers */
++ __wctdm_setcreg(wc, WC_CS, x);
++ y = __wctdm_getcreg(wc, WC_CS) & 0x0f;
++ if (x != y) {
++ printk(KERN_INFO "%02x != %02x\n", x, y);
++ failed++;
++ }
++ }
++
++ if (!failed) {
++ printk(KERN_INFO "OpenVox %s passed register test\n", wc->card_name);
++ } else {
++ printk(KERN_NOTICE "OpenVox %s failed register test\n", wc->card_name);
++ return -1;
++ }
++ } else {
++ printk(KERN_INFO "No OpenVox chip %02x\n", ver);
++ }
++
++ if (spibyhw)
++ __wctdm_setcreg(wc, WC_SPICTRL, BIT_SPI_BYHW); // spi controled by hw MiaoLin;
++ else
++ __wctdm_setcreg(wc, WC_SPICTRL, 0);
++
++ /* Reset PCI Interface chip and registers (and serial) */
++ outb(0x06, wc->ioaddr + WC_CNTL);
++ /* Setup our proper outputs for when we switch for our "serial" port */
++ wc->ios = BIT_CS | BIT_SCLK | BIT_SDI;
++
++ outb(wc->ios, wc->ioaddr + WC_AUXD);
++
++ /* Set all to outputs except AUX 5, which is an input */
++ outb(0xdf, wc->ioaddr + WC_AUXC);
++
++ /* Select alternate function for AUX0 */ /* Useless in OpenVox by MiaoLin. */
++ /* outb(0x4, wc->ioaddr + WC_AUXFUNC); */
++
++ /* Wait 1/4 of a sec */
++ wait_just_a_bit(HZ/4);
++
++ /* Back to normal, with automatic DMA wrap around */
++ outb(0x30 | 0x01, wc->ioaddr + WC_CNTL);
++ wc->ledstate = 0;
++ wctdm_set_led(wc, 0, 0);
++
++ /* Make sure serial port and DMA are out of reset */
++ outb(inb(wc->ioaddr + WC_CNTL) & 0xf9, wc->ioaddr + WC_CNTL);
++
++ /* Configure serial port for MSB->LSB operation */
++ outb(0xc1, wc->ioaddr + WC_SERCTL);
++
++ /* Delay FSC by 0 so it's properly aligned */
++ outb(0x01, wc->ioaddr + WC_FSCDELAY); /* Modify to 1 by MiaoLin */
++
++ /* Setup DMA Addresses */
++ outl(wc->writedma, wc->ioaddr + WC_DMAWS); /* Write start */
++ outl(wc->writedma + DAHDI_CHUNKSIZE * 4 * 4 - 4, wc->ioaddr + WC_DMAWI); /* Middle (interrupt) */
++ outl(wc->writedma + DAHDI_CHUNKSIZE * 8 * 4 - 4, wc->ioaddr + WC_DMAWE); /* End */
++
++ outl(wc->readdma, wc->ioaddr + WC_DMARS); /* Read start */
++ outl(wc->readdma + DAHDI_CHUNKSIZE * 4 * 4 - 4, wc->ioaddr + WC_DMARI); /* Middle (interrupt) */
++ outl(wc->readdma + DAHDI_CHUNKSIZE * 8 * 4 - 4, wc->ioaddr + WC_DMARE); /* End */
++
++ /* Clear interrupts */
++ outb(0xff, wc->ioaddr + WC_INTSTAT);
++
++ /* Wait 1/4 of a second more */
++ wait_just_a_bit(HZ/4);
++
++ for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
++ int sane=0,ret=0,readi=0;
++#if 1
++ touch_softlockup_watchdog(); // avoid showing CPU softlock message
++ /* Init with Auto Calibration */
++ if (!(ret=wctdm_init_proslic(wc, x, 0, 0, sane))) {
++ wc->cardflag |= (1 << x);
++ if (debug) {
++ readi = wctdm_getreg(wc,x,LOOP_I_LIMIT);
++ printk("Proslic module %d loop current is %dmA\n",x,
++ ((readi*3)+20));
++ }
++ printk(KERN_INFO "Module %d: Installed -- AUTO FXS/DPO\n",x);
++ wctdm_set_led(wc, (unsigned int)x, 1);
++ } else {
++ if(ret!=-2) {
++ sane=1;
++
++ printk(KERN_INFO "Init ProSlic with Manual Calibration \n");
++ /* Init with Manual Calibration */
++ if (!wctdm_init_proslic(wc, x, 0, 1, sane)) {
++ wc->cardflag |= (1 << x);
++ if (debug) {
++ readi = wctdm_getreg(wc,x,LOOP_I_LIMIT);
++ printk("Proslic module %d loop current is %dmA\n",x,
++ ((readi*3)+20));
++ }
++ printk(KERN_INFO "Module %d: Installed -- MANUAL FXS\n",x);
++ } else {
++ printk(KERN_NOTICE "Module %d: FAILED FXS (%s)\n", x, fxshonormode ? fxo_modes[_opermode].name : "FCC");
++ wc->chans[x]->sigcap = __DAHDI_SIG_FXO | DAHDI_SIG_BROKEN;
++ }
++ } else if (!(ret = wctdm_init_voicedaa(wc, x, 0, 0, sane))) {
++ wc->cardflag |= (1 << x);
++ printk(KERN_INFO "Module %d: Installed -- AUTO FXO (%s mode)\n",x, fxo_modes[_opermode].name);
++ wctdm_set_led(wc, (unsigned int)x, 1);
++ } else
++ printk(KERN_NOTICE "Module %d: Not installed\n", x);
++ }
++#endif
++ }
++
++ /* Return error if nothing initialized okay. */
++ if (!wc->cardflag && !timingonly)
++ return -1;
++ /*__wctdm_setcreg(wc, WC_SYNC, (wc->cardflag << 1) | 0x1); */ /* removed by MiaoLin */
++ return 0;
++}
++
++static void wctdm_enable_interrupts(struct wctdm *wc)
++{
++ /* Clear interrupts */
++ outb(0xff, wc->ioaddr + WC_INTSTAT);
++
++ /* Enable interrupts (we care about all of them) */
++ outb(0x3c, wc->ioaddr + WC_MASK0);
++ /* No external interrupts */
++ outb(0x00, wc->ioaddr + WC_MASK1);
++}
++
++static void wctdm_restart_dma(struct wctdm *wc)
++{
++ /* Reset Master and TDM */
++ outb(0x01, wc->ioaddr + WC_CNTL);
++ outb(0x01, wc->ioaddr + WC_OPER);
++}
++
++static void wctdm_start_dma(struct wctdm *wc)
++{
++ /* Reset Master and TDM */
++ outb(0x0f, wc->ioaddr + WC_CNTL);
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule_timeout(1);
++ outb(0x01, wc->ioaddr + WC_CNTL);
++ outb(0x01, wc->ioaddr + WC_OPER);
++}
++
++static void wctdm_stop_dma(struct wctdm *wc)
++{
++ outb(0x00, wc->ioaddr + WC_OPER);
++}
++
++static void wctdm_reset_tdm(struct wctdm *wc)
++{
++ /* Reset TDM */
++ outb(0x0f, wc->ioaddr + WC_CNTL);
++}
++
++static void wctdm_disable_interrupts(struct wctdm *wc)
++{
++ outb(0x00, wc->ioaddr + WC_MASK0);
++ outb(0x00, wc->ioaddr + WC_MASK1);
++}
++
++static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
++{
++ int res;
++ struct wctdm *wc;
++ struct wctdm_desc *d = (struct wctdm_desc *)ent->driver_data;
++ int x;
++ int y;
++
++ static int initd_ifaces=0;
++
++ if(initd_ifaces){
++ memset((void *)ifaces,0,(sizeof(struct wctdm *))*WC_MAX_IFACES);
++ initd_ifaces=1;
++ }
++ for (x=0;x<WC_MAX_IFACES;x++)
++ if (!ifaces[x]) break;
++ if (x >= WC_MAX_IFACES) {
++ printk(KERN_NOTICE "Too many interfaces\n");
++ return -EIO;
++ }
++
++ if (pci_enable_device(pdev)) {
++ res = -EIO;
++ } else {
++ wc = kmalloc(sizeof(struct wctdm), GFP_KERNEL);
++ if (wc) {
++ int cardcount = 0;
++
++ wc->lastchan = -1; /* first channel offset = -1; */
++ wc->ledstate = 0;
++
++ ifaces[x] = wc;
++ memset(wc, 0, sizeof(struct wctdm));
++ for (x=0; x < sizeof(wc->chans)/sizeof(wc->chans[0]); ++x) {
++ wc->chans[x] = &wc->_chans[x];
++ }
++
++ spin_lock_init(&wc->lock);
++ wc->curcard = -1;
++ wc->ioaddr = pci_resource_start(pdev, 0);
++ wc->mem_region = pci_resource_start(pdev, 1);
++ wc->mem_len = pci_resource_len(pdev, 1);
++ wc->mem32 = (unsigned long)ioremap(wc->mem_region, wc->mem_len);
++ wc->dev = pdev;
++ wc->pos = x;
++ wc->variety = d->name;
++ for (y=0;y<MAX_NUM_CARDS;y++)
++ wc->flags[y] = d->flags;
++ /* Keep track of whether we need to free the region */
++ if (request_region(wc->ioaddr, 0xff, "opvxa1200"))
++ wc->freeregion = 1;
++ else
++ wc->freeregion = 0;
++
++ if (request_mem_region(wc->mem_region, wc->mem_len, "opvxa1200"))
++ wc->freeregion |= 0x02;
++
++ /* Allocate enough memory for two zt chunks, receive and transmit. Each sample uses
++ 8 bits. */
++ wc->writechunk = pci_alloc_consistent(pdev, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, &wc->writedma);
++ if (!wc->writechunk) {
++ printk(KERN_NOTICE "opvxa1200: Unable to allocate DMA-able memory\n");
++ if (wc->freeregion & 0x01)
++ release_region(wc->ioaddr, 0xff);
++ if (wc->freeregion & 0x02)
++ {
++ release_mem_region(wc->mem_region, wc->mem_len);
++ iounmap((void *)wc->mem32);
++ }
++ return -ENOMEM;
++ }
++
++ wc->readchunk = wc->writechunk + DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2; /* in bytes */
++ wc->readdma = wc->writedma + DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2; /* in bytes */
++
++ if (wctdm_initialize(wc)) {
++ printk(KERN_NOTICE "opvxa1200: Unable to intialize FXS\n");
++ /* Set Reset Low */
++ x=inb(wc->ioaddr + WC_CNTL);
++ outb((~0x1)&x, wc->ioaddr + WC_CNTL);
++ /* Free Resources */
++ free_irq(pdev->irq, wc);
++ if (wc->freeregion & 0x01)
++ release_region(wc->ioaddr, 0xff);
++ if (wc->freeregion & 0x02)
++ {
++ release_mem_region(wc->mem_region, wc->mem_len);
++ iounmap((void *)wc->mem32);
++ }
++ }
++
++ /* Enable bus mastering */
++ pci_set_master(pdev);
++
++ /* Keep track of which device we are */
++ pci_set_drvdata(pdev, wc);
++
++
++ if (request_irq(pdev->irq, wctdm_interrupt, IRQF_SHARED, "opvxa1200", wc)) {
++ printk(KERN_NOTICE "opvxa1200: Unable to request IRQ %d\n", pdev->irq);
++ if (wc->freeregion & 0x01)
++ release_region(wc->ioaddr, 0xff);
++ if (wc->freeregion & 0x02)
++ {
++ release_mem_region(wc->mem_region, wc->mem_len);
++ iounmap((void *)wc->mem32);
++ }
++ pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
++ pci_set_drvdata(pdev, NULL);
++ kfree(wc);
++ return -EIO;
++ }
++
++ if (wctdm_hardware_init(wc)) {
++ unsigned char w;
++
++ /* Set Reset Low */
++ w=inb(wc->ioaddr + WC_CNTL);
++ outb((~0x1)&w, wc->ioaddr + WC_CNTL);
++ /* Free Resources */
++ free_irq(pdev->irq, wc);
++ if (wc->freeregion & 0x01)
++ release_region(wc->ioaddr, 0xff);
++ if (wc->freeregion & 0x02)
++ {
++ release_mem_region(wc->mem_region, wc->mem_len);
++ iounmap((void *)wc->mem32);
++ }
++ pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
++ pci_set_drvdata(pdev, NULL);
++ dahdi_unregister_device(wc->ddev);
++ kfree(wc->ddev->location);
++ dahdi_free_device(wc->ddev);
++ kfree(wc);
++ return -EIO;
++
++ }
++
++#ifdef TEST_LOG_INCOME_VOICE
++ for(x=0; x<MAX_NUM_CARDS+NUM_FLAG; x++)
++ {
++ wc->voc_buf[x] = kmalloc(voc_buffer_size, GFP_KERNEL);
++ wc->voc_ptr[x] = 0;
++ }
++#endif
++
++ if(cidbeforering)
++ {
++ int len = cidbuflen * DAHDI_MAX_CHUNKSIZE;
++ if(debug)
++ printk("cidbeforering support enabled, length is %d msec\n", cidbuflen);
++ for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++)
++ {
++ wc->cid_history_buf[x] = kmalloc(len, GFP_KERNEL);
++ wc->cid_history_ptr[x] = 0;
++ wc->cid_history_clone_cnt[x] = 0;
++ wc->cid_state[x] = CID_STATE_IDLE;
++ }
++ }
++
++ wctdm_post_initialize(wc);
++
++ /* Enable interrupts */
++ wctdm_enable_interrupts(wc);
++ /* Initialize Write/Buffers to all blank data */
++ memset((void *)wc->writechunk,0, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2);
++
++ /* Start DMA */
++ wctdm_start_dma(wc);
++
++ for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++) {
++ if (wc->cardflag & (1 << x))
++ cardcount++;
++ }
++
++ printk(KERN_INFO "Found an OpenVox %s: Version %x.%x (%d modules)\n", wc->card_name, (wc->fwversion&(~FLAG_A800))>>4, wc->fwversion&0x0f, cardcount);
++ if(debug)
++ printk(KERN_DEBUG "OpenVox %s debug On\n", wc->card_name);
++
++ res = 0;
++ } else
++ res = -ENOMEM;
++ }
++ return res;
++}
++
++static void wctdm_release(struct wctdm *wc)
++{
++#ifdef TEST_LOG_INCOME_VOICE
++ struct file * f = NULL;
++ mm_segment_t orig_fs;
++ int i;
++ char fname[20];
++#endif
++
++ dahdi_unregister_device(wc->ddev);
++ kfree(wc->ddev->location);
++ dahdi_free_device(wc->ddev);
++ if (wc->freeregion & 0x01)
++ release_region(wc->ioaddr, 0xff);
++ if (wc->freeregion & 0x02)
++ {
++ release_mem_region(wc->mem_region, wc->mem_len);
++ iounmap((void *)wc->mem32);
++ }
++
++#ifdef TEST_LOG_INCOME_VOICE
++ for(i=0; i<MAX_NUM_CARDS + NUM_FLAG; i++)
++ {
++ sprintf(fname, "//usr//%d.pcm", i);
++ f = filp_open(fname, O_RDWR|O_CREAT, 00);
++
++ if (!f || !f->f_op || !f->f_op->read)
++ {
++ printk("WARNING: File (read) object is a null pointer!!!\n");
++ continue;
++ }
++
++ f->f_pos = 0;
++
++ orig_fs = get_fs();
++ set_fs(KERNEL_DS);
++
++ if(wc->voc_buf[i])
++ {
++ f->f_op->write(f, wc->voc_buf[i], voc_buffer_size, &f->f_pos);
++ kfree(wc->voc_buf[i]);
++ }
++
++ set_fs(orig_fs);
++ fput(f);
++ }
++#endif
++
++ if(cidbeforering)
++ {
++ int x;
++ for (x = 0; x < wc->max_cards/*MAX_NUM_CARDS*/; x++)
++ kfree(wc->cid_history_buf[x]);
++ }
++
++ kfree(wc);
++ printk(KERN_INFO "Free an OpenVox A1200 card\n");
++}
++
++static void __devexit wctdm_remove_one(struct pci_dev *pdev)
++{
++ struct wctdm *wc = pci_get_drvdata(pdev);
++ if (wc) {
++
++ /* Stop any DMA */
++ wctdm_stop_dma(wc);
++ wctdm_reset_tdm(wc);
++
++ /* In case hardware is still there */
++ wctdm_disable_interrupts(wc);
++
++ /* Immediately free resources */
++ pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * (MAX_NUM_CARDS+NUM_FLAG) * 2 * 2, (void *)wc->writechunk, wc->writedma);
++ free_irq(pdev->irq, wc);
++
++ /* Reset PCI chip and registers */
++ if(wc->fwversion > 0x11)
++ outb(0x0e, wc->ioaddr + WC_CNTL);
++ else
++ {
++ wc->ledstate = 0;
++ wctdm_set_led(wc,0,0); // power off all leds.
++ }
++
++ /* Release span, possibly delayed */
++ if (!wc->usecount)
++ wctdm_release(wc);
++ else
++ wc->dead = 1;
++ }
++}
++
++static struct pci_device_id wctdm_pci_tbl[] = {
++ { 0xe159, 0x0001, 0x9100, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
++ { 0xe159, 0x0001, 0x9519, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
++ { 0xe159, 0x0001, 0x95D9, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
++ { 0xe159, 0x0001, 0x9500, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
++ { 0xe159, 0x0001, 0x9532, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
++ { 0xe159, 0x0001, 0x8519, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
++ { 0xe159, 0x0001, 0x9559, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
++ { 0xe159, 0x0001, 0x9599, PCI_ANY_ID, 0, 0, (unsigned long) &wctdme },
++ { 0 }
++};
++
++MODULE_DEVICE_TABLE(pci, wctdm_pci_tbl);
++
++static struct pci_driver wctdm_driver = {
++ .name = "opvxa1200",
++ .probe = wctdm_init_one,
++ .remove = __devexit_p(wctdm_remove_one),
++ .suspend = NULL,
++ .resume = NULL,
++ .id_table = wctdm_pci_tbl,
++};
++
++static int __init wctdm_init(void)
++{
++ int res;
++ int x;
++ for (x=0;x<(sizeof(fxo_modes) / sizeof(fxo_modes[0])); x++) {
++ if (!strcmp(fxo_modes[x].name, opermode))
++ break;
++ }
++ if (x < sizeof(fxo_modes) / sizeof(fxo_modes[0])) {
++ _opermode = x;
++ } else {
++ printk(KERN_NOTICE "Invalid/unknown operating mode '%s' specified. Please choose one of:\n", opermode);
++ for (x=0;x<sizeof(fxo_modes) / sizeof(fxo_modes[0]); x++)
++ printk(KERN_INFO " %s\n", fxo_modes[x].name);
++ printk(KERN_INFO "Note this option is CASE SENSITIVE!\n");
++ return -ENODEV;
++ }
++ if (!strcmp(fxo_modes[_opermode].name, "AUSTRALIA")) {
++ boostringer=1;
++ fxshonormode=1;
++}
++ if (battdebounce == 0) {
++ battdebounce = fxo_modes[_opermode].battdebounce;
++ }
++ if (battalarm == 0) {
++ battalarm = fxo_modes[_opermode].battalarm;
++ }
++ if (battthresh == 0) {
++ battthresh = fxo_modes[_opermode].battthresh;
++ }
++
++ res = pci_register_driver(&wctdm_driver);
++ if (res)
++ return -ENODEV;
++ return 0;
++}
++
++static void __exit wctdm_cleanup(void)
++{
++ pci_unregister_driver(&wctdm_driver);
++}
++
++module_param(debug, int, 0600);
++module_param(loopcurrent, int, 0600);
++module_param(reversepolarity, int, 0600);
++module_param(robust, int, 0600);
++module_param(opermode, charp, 0600);
++module_param(timingonly, int, 0600);
++module_param(lowpower, int, 0600);
++module_param(boostringer, int, 0600);
++module_param(fastringer, int, 0600);
++module_param(fxshonormode, int, 0600);
++module_param(battdebounce, uint, 0600);
++module_param(battthresh, uint, 0600);
++module_param(battalarm, uint, 0600);
++module_param(ringdebounce, int, 0600);
++module_param(dialdebounce, int, 0600);
++module_param(fwringdetect, int, 0600);
++module_param(alawoverride, int, 0600);
++module_param(fastpickup, int, 0600);
++module_param(fxotxgain, int, 0600);
++module_param(fxorxgain, int, 0600);
++module_param(fxstxgain, int, 0600);
++module_param(fxsrxgain, int, 0600);
++module_param(spibyhw, int, 0600);
++module_param(usememio, int, 0600);
++module_param(cidbeforering, int, 0600);
++module_param(cidbuflen, int, 0600);
++module_param(cidtimeout, int, 0600);
++module_param(fxofullscale, int, 0600);
++module_param(fixedtimepolarity, int, 0600);
++
++MODULE_DESCRIPTION("OpenVox A1200 Driver");
++MODULE_AUTHOR("MiaoLin <miaolin@openvox.com.cn>");
++MODULE_LICENSE("GPL v2");
++
++module_init(wctdm_init);
++module_exit(wctdm_cleanup);
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/opvxa1200/Kbuild dahdi-extra-dahdi-linux/drivers/dahdi/opvxa1200/Kbuild
+--- dahdi-linux-2.7.0/drivers/dahdi/opvxa1200/Kbuild 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/opvxa1200/Kbuild 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,19 @@
++obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXA1200) += opvxa1200.o
++
++EXTRA_CFLAGS += -I$(src)/.. -Wno-undef
++
++opvxa1200-objs := base.o
++
++DAHDI_KERNEL_H_NAME:=kernel.h
++DAHDI_KERNEL_H_PATH:=$(DAHDI_INCLUDE)/dahdi/$(DAHDI_KERNEL_H_NAME)
++ifneq ($(DAHDI_KERNEL_H_PATH),)
++ DAHDI_SPAN_MODULE:=$(shell if grep -C 5 "struct dahdi_span {" $(DAHDI_KERNEL_H_PATH) | grep -q "struct module \*owner"; then echo "yes"; else echo "no"; fi)
++ DAHDI_SPAN_OPS:=$(shell if grep -q "struct dahdi_span_ops {" $(DAHDI_KERNEL_H_PATH); then echo "yes"; else echo "no"; fi)
++ ifeq ($(DAHDI_SPAN_MODULE),yes)
++ EXTRA_CFLAGS+=-DDAHDI_SPAN_MODULE
++ else
++ ifeq ($(DAHDI_SPAN_OPS),yes)
++ EXTRA_CFLAGS+=-DDAHDI_SPAN_OPS
++ endif
++ endif
++endif
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/opvxa1200/Makefile dahdi-extra-dahdi-linux/drivers/dahdi/opvxa1200/Makefile
+--- dahdi-linux-2.7.0/drivers/dahdi/opvxa1200/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/opvxa1200/Makefile 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,8 @@
++ifdef KBUILD_EXTMOD
++# We only get here on kernels 2.6.0-2.6.9 .
++# For newer kernels, Kbuild will be included directly by the kernel
++# build system.
++include $(src)/Kbuild
++
++else
++endif
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/opvxd115/base.c dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/base.c
+--- dahdi-linux-2.7.0/drivers/dahdi/opvxd115/base.c 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/base.c 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,4916 @@
++/*
++ * OpenVox D115P/D115E PCI/PCI-E Driver version 0.1 01/07/2011
++ *
++ * Written by Mark Spencer <markster@digium.com>
++ * Modify from wct4xxp module by mark.liu@openvox.cn
++
++ * Based on previous works, designs, and archetectures conceived and
++ * written by Jim Dixon <jim@lambdatel.com>.
++ *
++ * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
++ * Copyright (C) 2001-2010, Digium, Inc.
++ *
++ * All rights reserved.
++ *
++ */
++
++/*
++ * See http://www.asterisk.org for more information about
++ * the Asterisk project. Please do not directly contact
++ * any of the maintainers of this project for assistance;
++ * the project provides a web site, mailing lists and IRC
++ * channels for your use.
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License Version 2 as published by the
++ * Free Software Foundation. See the LICENSE file included with
++ * this program for more details.
++ */
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <asm/io.h>
++#include <linux/version.h>
++#include <linux/delay.h>
++#include <linux/moduleparam.h>
++
++#include <dahdi/kernel.h>
++
++#include "opvxd115.h"
++#include "vpm450m.h"
++
++/* Work queues are a way to better distribute load on SMP systems */
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
++/*
++ * Work queues can significantly improve performance and scalability
++ * on multi-processor machines, but requires bypassing some kernel
++ * API's, so it's not guaranteed to be compatible with all kernels.
++ */
++/* #define ENABLE_WORKQUEUES */
++#endif
++
++/* Enable prefetching may help performance */
++#define ENABLE_PREFETCH
++
++/* Support first generation cards? */
++#define SUPPORT_GEN1
++
++/* Define to get more attention-grabbing but slightly more I/O using
++ alarm status */
++#define FANCY_ALARM
++
++/* Define to support Digium Voice Processing Module expansion card */
++#define VPM_SUPPORT
++
++#define DEBUG_MAIN (1 << 0)
++#define DEBUG_DTMF (1 << 1)
++#define DEBUG_REGS (1 << 2)
++#define DEBUG_TSI (1 << 3)
++#define DEBUG_ECHOCAN (1 << 4)
++#define DEBUG_RBS (1 << 5)
++#define DEBUG_FRAMER (1 << 6)
++
++/* Maximum latency to be used with Gen 5 */
++#define GEN5_MAX_LATENCY 127
++
++#define T4_BASE_SIZE (DAHDI_MAX_CHUNKSIZE * 32 * 4)
++
++#ifndef IRQF_DISABLED
++#ifdef SA_INTERRUPT
++#define IRQF_DISABLED SA_INTERRUPT
++#else
++#define IRQF_DISABLED 0x0
++#endif
++#endif
++
++#ifdef ENABLE_WORKQUEUES
++#include <linux/cpu.h>
++
++/* XXX UGLY!!!! XXX We have to access the direct structures of the workqueue which
++ are only defined within workqueue.c because they don't give us a routine to allow us
++ to nail a work to a particular thread of the CPU. Nailing to threads gives us substantially
++ higher scalability in multi-CPU environments though! */
++
++/*
++ * The per-CPU workqueue (if single thread, we always use cpu 0's).
++ *
++ * The sequence counters are for flush_scheduled_work(). It wants to wait
++ * until until all currently-scheduled works are completed, but it doesn't
++ * want to be livelocked by new, incoming ones. So it waits until
++ * remove_sequence is >= the insert_sequence which pertained when
++ * flush_scheduled_work() was called.
++ */
++
++struct cpu_workqueue_struct {
++
++ spinlock_t lock;
++
++ long remove_sequence; /* Least-recently added (next to run) */
++ long insert_sequence; /* Next to add */
++
++ struct list_head worklist;
++ wait_queue_head_t more_work;
++ wait_queue_head_t work_done;
++
++ struct workqueue_struct *wq;
++ task_t *thread;
++
++ int run_depth; /* Detect run_workqueue() recursion depth */
++} ____cacheline_aligned;
++
++/*
++ * The externally visible workqueue abstraction is an array of
++ * per-CPU workqueues:
++ */
++struct workqueue_struct {
++ /* TODO: Find out exactly where the API changed */
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
++ struct cpu_workqueue_struct *cpu_wq;
++#else
++ struct cpu_workqueue_struct cpu_wq[NR_CPUS];
++#endif
++ const char *name;
++ struct list_head list; /* Empty if single thread */
++};
++
++/* Preempt must be disabled. */
++static void __t4_queue_work(struct cpu_workqueue_struct *cwq,
++ struct work_struct *work)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&cwq->lock, flags);
++ work->wq_data = cwq;
++ list_add_tail(&work->entry, &cwq->worklist);
++ cwq->insert_sequence++;
++ wake_up(&cwq->more_work);
++ spin_unlock_irqrestore(&cwq->lock, flags);
++}
++
++/*
++ * Queue work on a workqueue. Return non-zero if it was successfully
++ * added.
++ *
++ * We queue the work to the CPU it was submitted, but there is no
++ * guarantee that it will be processed by that CPU.
++ */
++static inline int t4_queue_work(struct workqueue_struct *wq, struct work_struct *work, int cpu)
++{
++ int ret = 0;
++ get_cpu();
++ if (!test_and_set_bit(0, &work->pending)) {
++ BUG_ON(!list_empty(&work->entry));
++ __t4_queue_work(wq->cpu_wq + cpu, work);
++ ret = 1;
++ }
++ put_cpu();
++ return ret;
++}
++
++#endif
++
++/*
++ * Define CONFIG_EXTENDED_RESET to allow the qfalc framer extra time
++ * to reset itself upon hardware initialization. This exits for rare
++ * cases for customers who are seeing the qfalc returning unexpected
++ * information at initialization
++ */
++#undef CONFIG_EXTENDED_RESET
++
++static int pedanticpci = 1;
++static int debug=0;
++static int timingcable = 0;
++static int t1e1override = -1; /* 0xff for E1, 0x00 for T1 */
++static int j1mode = 0;
++static int sigmode = FRMR_MODE_NO_ADDR_CMP;
++static int alarmdebounce = 2500; /* LOF/LFA def to 2.5s AT&T TR54016*/
++static int losalarmdebounce = 2500;/* LOS def to 2.5s AT&T TR54016*/
++static int aisalarmdebounce = 2500;/* AIS(blue) def to 2.5s AT&T TR54016*/
++static int yelalarmdebounce = 500;/* RAI(yellow) def to 0.5s AT&T devguide */
++static int max_latency = GEN5_MAX_LATENCY; /* Used to set a maximum latency (if you don't wish it to hard cap it at a certain value) in milliseconds */
++#ifdef VPM_SUPPORT
++static int vpmsupport = 1;
++/* If set to auto, vpmdtmfsupport is enabled for VPM400M and disabled for VPM450M */
++static int vpmdtmfsupport = -1; /* -1=auto, 0=disabled, 1=enabled*/
++static int vpmspans = 1;
++#define VPM_DEFAULT_DTMFTHRESHOLD 1000
++static int dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
++static int lastdtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
++#endif
++/* Enabling bursting can more efficiently utilize PCI bus bandwidth, but
++ can also cause PCI bus starvation, especially in combination with other
++ aggressive cards. Please note that burst mode has no effect on CPU
++ utilization / max number of calls / etc. */
++static int noburst;
++/* For 56kbps links, set this module parameter to 0x7f */
++static int hardhdlcmode = 0xff;
++
++static int latency = 1;
++
++static int ms_per_irq = 1;
++
++#ifdef FANCY_ALARM
++static int altab[] = {
++0, 0, 0, 1, 2, 3, 4, 6, 8, 9, 11, 13, 16, 18, 20, 22, 24, 25, 27, 28, 29, 30, 31, 31, 32, 31, 31, 30, 29, 28, 27, 25, 23, 22, 20, 18, 16, 13, 11, 9, 8, 6, 4, 3, 2, 1, 0, 0,
++};
++#endif
++
++#define MAX_SPANS 16
++
++#define FLAG_STARTED (1 << 0)
++#define FLAG_NMF (1 << 1)
++#define FLAG_SENDINGYELLOW (1 << 2)
++
++
++#define TYPE_T1 1 /* is a T1 card */
++#define TYPE_E1 2 /* is an E1 card */
++#define TYPE_J1 3 /* is a running J1 */
++
++#define FLAG_2NDGEN (1 << 3)
++#define FLAG_2PORT (1 << 4)
++#define FLAG_VPM2GEN (1 << 5)
++#define FLAG_OCTOPT (1 << 6)
++#define FLAG_3RDGEN (1 << 7)
++#define FLAG_BURST (1 << 8)
++#define FLAG_5THGEN (1 << 10)
++
++#define CANARY 0xc0de
++
++
++#define PORTS_PER_FRAMER 4
++
++struct devtype {
++ char *desc;
++ unsigned int flags;
++};
++
++static struct devtype opvxd115 = { "OpenVox D115P/D115E ", FLAG_2NDGEN};
++static struct devtype opvxd130 = { "OpenVox D130P/D130E", FLAG_5THGEN | FLAG_BURST | FLAG_2NDGEN | FLAG_3RDGEN};
++
++
++struct t4;
++
++struct t4_span {
++ struct t4 *owner;
++ unsigned int *writechunk; /* Double-word aligned write memory */
++ unsigned int *readchunk; /* Double-word aligned read memory */
++ int spantype; /* card type, T1 or E1 or J1 */
++ int sync;
++ int psync;
++ int alarmtimer;
++ int redalarms;
++ int notclear;
++ int alarmcount;
++ int losalarmcount;
++ int aisalarmcount;
++ int yelalarmcount;
++ int spanflags;
++ int syncpos;
++#ifdef SUPPORT_GEN1
++ int e1check; /* E1 check */
++#endif
++ struct dahdi_span span;
++ unsigned char txsigs[16]; /* Transmit sigs */
++ int loopupcnt;
++ int loopdowncnt;
++#ifdef SUPPORT_GEN1
++ unsigned char ec_chunk1[31][DAHDI_CHUNKSIZE]; /* first EC chunk buffer */
++ unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE]; /* second EC chunk buffer */
++#endif
++ int irqmisses;
++
++ /* HDLC controller fields */
++ struct dahdi_chan *sigchan;
++ unsigned char sigmode;
++ int sigactive;
++ int frames_out;
++ int frames_in;
++
++#ifdef VPM_SUPPORT
++ unsigned long dtmfactive;
++ unsigned long dtmfmask;
++ unsigned long dtmfmutemask;
++ short dtmfenergy[31];
++ short dtmfdigit[31];
++#endif
++#ifdef ENABLE_WORKQUEUES
++ struct work_struct swork;
++#endif
++ struct dahdi_chan *chans[32]; /* Individual channels */
++ struct dahdi_echocan_state *ec[32]; /* Echocan state for each channel */
++};
++
++struct t4 {
++ /* This structure exists one per card */
++ struct pci_dev *dev; /* Pointer to PCI device */
++ struct dahdi_device *ddev; /* Pointer to DAHDI device */
++ unsigned int intcount;
++ int num; /* Which card we are */
++ int t1e1; /* T1/E1 select pins */
++ int globalconfig; /* Whether global setup has been done */
++ int syncsrc; /* active sync source */
++ struct t4_span *tspans[4]; /* Individual spans */
++ int numspans; /* Number of spans on the card */
++ int blinktimer;
++#ifdef FANCY_ALARM
++ int alarmpos;
++#endif
++ int irq; /* IRQ used by device */
++ int order; /* Order */
++ int flags; /* Device flags */
++ unsigned int falc31 : 1; /* are we falc v3.1 (atomic not necessary) */
++ int master; /* Are we master */
++ int ledreg; /* LED Register */
++ unsigned int gpio;
++ unsigned int gpioctl;
++ int e1recover; /* E1 recovery timer */
++ spinlock_t reglock; /* lock register access */
++ int spansstarted; /* number of spans started */
++ volatile unsigned int *writechunk; /* Double-word aligned write memory */
++ volatile unsigned int *readchunk; /* Double-word aligned read memory */
++ unsigned short canary;
++#ifdef ENABLE_WORKQUEUES
++ atomic_t worklist;
++ struct workqueue_struct *workq;
++#endif
++ unsigned int passno; /* number of interrupt passes */
++ char *variety;
++ int last0; /* for detecting double-missed IRQ */
++
++ /* DMA related fields */
++ unsigned int dmactrl;
++ dma_addr_t readdma;
++ dma_addr_t writedma;
++ unsigned long memaddr; /* Base address of card */
++ unsigned long memlen;
++ __iomem volatile unsigned int *membase; /* Base address of card */
++
++ /* Add this for our softlockup protector */
++ unsigned int oct_rw_count;
++
++ /* Flags for our bottom half */
++ unsigned long checkflag;
++ struct tasklet_struct t4_tlet;
++ unsigned int vpm400checkstatus;
++ /* Latency related additions */
++ unsigned char rxident;
++ unsigned char lastindex;
++ int numbufs;
++ int needed_latency;
++
++#ifdef VPM_SUPPORT
++ struct vpm450m *vpm450m;
++ int vpm;
++#endif
++
++};
++
++#define T4_VPM_PRESENT (1 << 28)
++
++#ifdef VPM_SUPPORT
++static void t4_vpm400_init(struct t4 *wc);
++static void t4_vpm450_init(struct t4 *wc);
++static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold);
++
++static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
++
++static const struct dahdi_echocan_features vpm400m_ec_features = {
++ .NLP_automatic = 1,
++ .CED_tx_detect = 1,
++ .CED_rx_detect = 1,
++};
++
++static const struct dahdi_echocan_features vpm450m_ec_features = {
++ .NLP_automatic = 1,
++ .CED_tx_detect = 1,
++ .CED_rx_detect = 1,
++};
++
++static const struct dahdi_echocan_ops vpm400m_ec_ops = {
++ .echocan_free = echocan_free,
++};
++
++static const struct dahdi_echocan_ops vpm450m_ec_ops = {
++ .echocan_free = echocan_free,
++};
++#endif
++
++static void __set_clear(struct t4 *wc, int span);
++static int t4_startup(struct file *file, struct dahdi_span *span);
++static int t4_shutdown(struct dahdi_span *span);
++static int t4_rbsbits(struct dahdi_chan *chan, int bits);
++static int t4_maint(struct dahdi_span *span, int cmd);
++static int t4_clear_maint(struct dahdi_span *span);
++#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
++static int t4_reset_counters(struct dahdi_span *span);
++#endif
++#ifdef SUPPORT_GEN1
++static int t4_reset_dma(struct t4 *wc);
++#endif
++static void t4_hdlc_hard_xmit(struct dahdi_chan *chan);
++static int t4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data);
++static void t4_tsi_assign(struct t4 *wc, int fromspan, int fromchan, int tospan, int tochan);
++static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan);
++static void __t4_set_rclk_src(struct t4 *wc, int span);
++static void __t4_set_sclk_src(struct t4 *wc, int mode, int master, int slave);
++static void t4_check_alarms(struct t4 *wc, int span);
++static void t4_check_sigbits(struct t4 *wc, int span);
++
++#define WC_RDADDR 0
++#define WC_WRADDR 1
++#define WC_COUNT 2
++#define WC_DMACTRL 3
++#define WC_INTR 4
++/* #define WC_GPIO 5 */
++#define WC_VERSION 6
++#define WC_LEDS 7
++#define WC_GPIOCTL 8
++#define WC_GPIO 9
++#define WC_LADDR 10
++#define WC_LDATA 11
++#define WC_LCS (1 << 11)
++#define WC_LCS2 (1 << 12)
++#define WC_LALE (1 << 13)
++#define WC_LFRMR_CS (1 << 10) /* Framer's ChipSelect signal */
++#define WC_ACTIVATE (1 << 12)
++#define WC_LREAD (1 << 15)
++#define WC_LWRITE (1 << 16)
++
++#define WC_OFF (0)
++#define WC_RED (1)
++#define WC_GREEN (2)
++#define WC_YELLOW (3)
++
++#define WC_RECOVER 0
++#define WC_SELF 1
++
++#define LIM0_T 0x36 /* Line interface mode 0 register */
++#define LIM0_LL (1 << 1) /* Local Loop */
++#define LIM1_T 0x37 /* Line interface mode 1 register */
++#define LIM1_RL (1 << 1) /* Remote Loop */
++
++#define FMR0 0x1C /* Framer Mode Register 0 */
++#define FMR0_SIM (1 << 0) /* Alarm Simulation */
++#define FMR1_T 0x1D /* Framer Mode Register 1 */
++#define FMR1_ECM (1 << 2) /* Error Counter 1sec Interrupt Enable */
++#define DEC_T 0x60 /* Diable Error Counter */
++#define IERR_T 0x1B /* Single Bit Defect Insertion Register */
++#define IBV 0 /* Bipolar violation */
++#define IPE (1 << 1) /* PRBS defect */
++#define ICASE (1 << 2) /* CAS defect */
++#define ICRCE (1 << 3) /* CRC defect */
++#define IMFE (1 << 4) /* Multiframe defect */
++#define IFASE (1 << 5) /* FAS defect */
++#define ISR3_SEC (1 << 6) /* Internal one-second interrupt bit mask */
++#define ISR3_ES (1 << 7) /* Errored Second interrupt bit mask */
++#define ESM 0x47 /* Errored Second mask register */
++
++#define FMR2_T 0x1E /* Framer Mode Register 2 */
++#define FMR2_PLB (1 << 2) /* Framer Mode Register 2 */
++
++#define FECL_T 0x50 /* Framing Error Counter Lower Byte */
++#define FECH_T 0x51 /* Framing Error Counter Higher Byte */
++#define CVCL_T 0x52 /* Code Violation Counter Lower Byte */
++#define CVCH_T 0x53 /* Code Violation Counter Higher Byte */
++#define CEC1L_T 0x54 /* CRC Error Counter 1 Lower Byte */
++#define CEC1H_T 0x55 /* CRC Error Counter 1 Higher Byte */
++#define EBCL_T 0x56 /* E-Bit Error Counter Lower Byte */
++#define EBCH_T 0x57 /* E-Bit Error Counter Higher Byte */
++#define BECL_T 0x58 /* Bit Error Counter Lower Byte */
++#define BECH_T 0x59 /* Bit Error Counter Higher Byte */
++#define COEC_T 0x5A /* COFA Event Counter */
++#define PRBSSTA_T 0xDA /* PRBS Status Register */
++
++#define LCR1_T 0x3B /* Loop Code Register 1 */
++#define EPRM (1 << 7) /* Enable PRBS rx */
++#define XPRBS (1 << 6) /* Enable PRBS tx */
++#define FLLB (1 << 1) /* Framed line loop/Invert */
++#define LLBP (1 << 0) /* Line Loopback Pattern */
++#define TPC0_T 0xA8 /* Test Pattern Control Register */
++#define FRA (1 << 6) /* Framed/Unframed Selection */
++#define PRBS23 (3 << 4) /* Pattern selection (23 poly) */
++#define PRM (1 << 2) /* Non framed mode */
++#define FRS1_T 0x4D /* Framer Receive Status Reg 1 */
++#define LLBDD (1 << 4)
++#define LLBAD (1 << 3)
++
++#define MAX_T4_CARDS 64
++
++static void t4_isr_bh(unsigned long data);
++
++static struct t4 *cards[MAX_T4_CARDS];
++
++
++#define MAX_TDM_CHAN 32
++#define MAX_DTMF_DET 16
++
++#define HDLC_IMR0_MASK (FRMR_IMR0_RME | FRMR_IMR0_RPF)
++#if 0
++#define HDLC_IMR1_MASK (FRMR_IMR1_ALLS | FRMR_IMR1_XDU | FRMR_IMR1_XPR)
++#else
++#define HDLC_IMR1_MASK (FRMR_IMR1_XDU | FRMR_IMR1_XPR)
++#endif
++
++static inline unsigned int __t4_pci_in(struct t4 *wc, const unsigned int addr)
++{
++ unsigned int res = readl(&wc->membase[addr]);
++ return res;
++}
++
++static inline void __t4_pci_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
++{
++ unsigned int tmp;
++ writel(value, &wc->membase[addr]);
++ if (pedanticpci) {
++ tmp = __t4_pci_in(wc, WC_VERSION);
++ if ((tmp & 0xffff0000) != 0xc01a0000)
++ dev_notice(&wc->dev->dev,
++ "Version Synchronization Error!\n");
++ }
++#if 0
++ tmp = __t4_pci_in(wc, addr);
++ if ((value != tmp) && (addr != WC_LEDS) && (addr != WC_LDATA) &&
++ (addr != WC_GPIO) && (addr != WC_INTR))
++ dev_info(&wc->dev->dev, "Tried to load %08x into %08x, "
++ "but got %08x instead\n", value, addr, tmp);
++#endif
++}
++
++static inline void __t4_gpio_set(struct t4 *wc, unsigned bits, unsigned int val)
++{
++ unsigned int newgpio;
++ newgpio = wc->gpio & (~bits);
++ newgpio |= val;
++ if (newgpio != wc->gpio) {
++ wc->gpio = newgpio;
++ __t4_pci_out(wc, WC_GPIO, wc->gpio);
++ }
++}
++
++static inline void __t4_gpio_setdir(struct t4 *wc, unsigned int bits, unsigned int val)
++{
++ unsigned int newgpioctl;
++ newgpioctl = wc->gpioctl & (~bits);
++ newgpioctl |= val;
++ if (newgpioctl != wc->gpioctl) {
++ wc->gpioctl = newgpioctl;
++ __t4_pci_out(wc, WC_GPIOCTL, wc->gpioctl);
++ }
++}
++
++static inline void t4_gpio_setdir(struct t4 *wc, unsigned int bits, unsigned int val)
++{
++ unsigned long flags;
++ spin_lock_irqsave(&wc->reglock, flags);
++ __t4_gpio_setdir(wc, bits, val);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++}
++
++static inline void t4_gpio_set(struct t4 *wc, unsigned int bits, unsigned int val)
++{
++ unsigned long flags;
++ spin_lock_irqsave(&wc->reglock, flags);
++ __t4_gpio_set(wc, bits, val);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++}
++
++static inline void t4_pci_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
++{
++ unsigned long flags;
++ spin_lock_irqsave(&wc->reglock, flags);
++ __t4_pci_out(wc, addr, value);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++}
++
++static inline void __t4_set_led(struct t4 *wc, int span, int color)
++{
++ int oldreg = wc->ledreg;
++ wc->ledreg &= ~(0x3 << (span << 1));
++ wc->ledreg |= (color << (span << 1));
++ if (oldreg != wc->ledreg)
++ __t4_pci_out(wc, WC_LEDS, wc->ledreg);
++}
++
++static inline void t4_activate(struct t4 *wc)
++{
++ wc->ledreg |= WC_ACTIVATE;
++ t4_pci_out(wc, WC_LEDS, wc->ledreg);
++}
++
++static inline unsigned int t4_pci_in(struct t4 *wc, const unsigned int addr)
++{
++ unsigned int ret;
++ unsigned long flags;
++
++ spin_lock_irqsave(&wc->reglock, flags);
++ ret = __t4_pci_in(wc, addr);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ return ret;
++}
++
++static inline unsigned int __t4_framer_in(struct t4 *wc, int unit, const unsigned int addr)
++{
++ unsigned int ret;
++ unit &= 0x3;
++ __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++ __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LREAD);
++ if (!pedanticpci) {
++ __t4_pci_in(wc, WC_VERSION);
++ } else {
++ __t4_pci_out(wc, WC_VERSION, 0);
++ }
++ ret = __t4_pci_in(wc, WC_LDATA);
++ __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
++
++ if (unlikely(debug & DEBUG_REGS))
++ dev_info(&wc->dev->dev, "Reading unit %d address %02x is "
++ "%02x\n", unit, addr, ret & 0xff);
++
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++
++ return ret & 0xff;
++}
++
++static inline unsigned int t4_framer_in(struct t4 *wc, int unit, const unsigned int addr)
++{
++ unsigned long flags;
++ unsigned int ret;
++ spin_lock_irqsave(&wc->reglock, flags);
++ ret = __t4_framer_in(wc, unit, addr);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ return ret;
++
++}
++
++static inline void __t4_framer_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
++{
++ unit &= 0x3;
++ if (unlikely(debug & DEBUG_REGS))
++ dev_info(&wc->dev->dev, "Writing %02x to address %02x of "
++ "unit %d\n", value, addr, unit);
++ __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
++ __t4_pci_out(wc, WC_LDATA, value);
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++ __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff) | WC_LFRMR_CS | WC_LWRITE);
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++ __t4_pci_out(wc, WC_LADDR, (unit << 8) | (addr & 0xff));
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++ if (unlikely(debug & DEBUG_REGS))
++ dev_info(&wc->dev->dev, "Write complete\n");
++#if 0
++ if ((addr != FRMR_TXFIFO) && (addr != FRMR_CMDR) && (addr != 0xbc))
++ { unsigned int tmp;
++ tmp = __t4_framer_in(wc, unit, addr);
++ if (tmp != value) {
++ dev_notice(&wc->dev->dev, "Expected %d from unit %d "
++ "register %d but got %d instead\n",
++ value, unit, addr, tmp);
++ } }
++#endif
++}
++
++static inline void t4_framer_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
++{
++ unsigned long flags;
++ spin_lock_irqsave(&wc->reglock, flags);
++ __t4_framer_out(wc, unit, addr, value);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++}
++
++#ifdef VPM_SUPPORT
++
++static inline void wait_a_little(void)
++{
++ unsigned long newjiffies=jiffies+2;
++ while(jiffies < newjiffies);
++}
++
++static inline unsigned int __t4_vpm_in(struct t4 *wc, int unit, const unsigned int addr)
++{
++ unsigned int ret;
++ unit &= 0x7;
++ __t4_pci_out(wc, WC_LADDR, (addr & 0x1ff) | ( unit << 12));
++ __t4_pci_out(wc, WC_LADDR, (addr & 0x1ff) | ( unit << 12) | (1 << 11) | WC_LREAD);
++ ret = __t4_pci_in(wc, WC_LDATA);
++ __t4_pci_out(wc, WC_LADDR, 0);
++ return ret & 0xff;
++}
++
++static inline void __t4_raw_oct_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
++{
++ int octopt = wc->tspans[0]->spanflags & FLAG_OCTOPT;
++ if (!octopt)
++ __t4_gpio_set(wc, 0xff, (addr >> 8));
++ __t4_pci_out(wc, WC_LDATA, 0x10000 | (addr & 0xffff));
++ if (!octopt)
++ __t4_pci_out(wc, WC_LADDR, (WC_LWRITE));
++ __t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE));
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++ if (!octopt)
++ __t4_gpio_set(wc, 0xff, (value >> 8));
++ __t4_pci_out(wc, WC_LDATA, (value & 0xffff));
++ __t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE | WC_LCS));
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++ __t4_pci_out(wc, WC_LADDR, (0));
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++}
++
++static inline unsigned int __t4_raw_oct_in(struct t4 *wc, const unsigned int addr)
++{
++ unsigned int ret;
++ int octopt = wc->tspans[0]->spanflags & FLAG_OCTOPT;
++ if (!octopt)
++ __t4_gpio_set(wc, 0xff, (addr >> 8));
++ __t4_pci_out(wc, WC_LDATA, 0x10000 | (addr & 0xffff));
++ if (!octopt)
++ __t4_pci_out(wc, WC_LADDR, (WC_LWRITE));
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++ __t4_pci_out(wc, WC_LADDR, (WC_LWRITE | WC_LALE));
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++#ifdef PEDANTIC_OCTASIC_CHECKING
++ __t4_pci_out(wc, WC_LADDR, (WC_LALE));
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++#endif
++ if (!octopt) {
++ __t4_gpio_setdir(wc, 0xff, 0x00);
++ __t4_gpio_set(wc, 0xff, 0x00);
++ }
++ __t4_pci_out(wc, WC_LADDR, (WC_LREAD | WC_LALE | WC_LCS));
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++ if (octopt) {
++ ret = __t4_pci_in(wc, WC_LDATA) & 0xffff;
++ } else {
++ ret = __t4_pci_in(wc, WC_LDATA) & 0xff;
++ ret |= (__t4_pci_in(wc, WC_GPIO) & 0xff) << 8;
++ }
++ __t4_pci_out(wc, WC_LADDR, (0));
++ if (!pedanticpci)
++ __t4_pci_in(wc, WC_VERSION);
++ if (!octopt)
++ __t4_gpio_setdir(wc, 0xff, 0xff);
++ return ret & 0xffff;
++}
++
++static inline unsigned int __t4_oct_in(struct t4 *wc, unsigned int addr)
++{
++#ifdef PEDANTIC_OCTASIC_CHECKING
++ int count = 1000;
++#endif
++ __t4_raw_oct_out(wc, 0x0008, (addr >> 20));
++ __t4_raw_oct_out(wc, 0x000a, (addr >> 4) & ((1 << 16) - 1));
++ __t4_raw_oct_out(wc, 0x0000, (((addr >> 1) & 0x7) << 9) | (1 << 8) | (1));
++#ifdef PEDANTIC_OCTASIC_CHECKING
++ while((__t4_raw_oct_in(wc, 0x0000) & (1 << 8)) && --count);
++ if (count != 1000)
++ dev_notice(&wc->dev->dev, "Yah, read can be slow...\n");
++ if (!count)
++ dev_notice(&wc->dev->dev, "Read timed out!\n");
++#endif
++ return __t4_raw_oct_in(wc, 0x0004);
++}
++
++static inline unsigned int t4_oct_in(struct t4 *wc, const unsigned int addr)
++{
++ unsigned long flags;
++ unsigned int ret;
++
++ spin_lock_irqsave(&wc->reglock, flags);
++ ret = __t4_oct_in(wc, addr);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ return ret;
++}
++
++static inline unsigned int t4_vpm_in(struct t4 *wc, int unit, const unsigned int addr)
++{
++ unsigned long flags;
++ unsigned int ret;
++ spin_lock_irqsave(&wc->reglock, flags);
++ ret = __t4_vpm_in(wc, unit, addr);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ return ret;
++}
++
++static inline void __t4_vpm_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
++{
++ unit &= 0x7;
++ if (debug & DEBUG_REGS)
++ dev_notice(&wc->dev->dev, "Writing %02x to address %02x of "
++ "ec unit %d\n", value, addr, unit);
++ __t4_pci_out(wc, WC_LADDR, (addr & 0xff));
++ __t4_pci_out(wc, WC_LDATA, value);
++ __t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11));
++ __t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11) | WC_LWRITE);
++ __t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff) | (1 << 11));
++ __t4_pci_out(wc, WC_LADDR, (unit << 12) | (addr & 0x1ff));
++ __t4_pci_out(wc, WC_LADDR, 0);
++ if (debug & DEBUG_REGS)
++ dev_notice(&wc->dev->dev, "Write complete\n");
++
++
++#if 0
++ { unsigned int tmp;
++ tmp = t4_vpm_in(wc, unit, addr);
++ if (tmp != value) {
++ dev_notice(&wc->dev->dev, "Expected %d from unit %d echo "
++ "register %d but got %d instead\n",
++ value, unit, addr, tmp);
++ } }
++#endif
++}
++
++static inline void __t4_oct_out(struct t4 *wc, unsigned int addr, unsigned int value)
++{
++#ifdef PEDANTIC_OCTASIC_CHECKING
++ int count = 1000;
++#endif
++ __t4_raw_oct_out(wc, 0x0008, (addr >> 20));
++ __t4_raw_oct_out(wc, 0x000a, (addr >> 4) & ((1 << 16) - 1));
++ __t4_raw_oct_out(wc, 0x0004, value);
++ __t4_raw_oct_out(wc, 0x0000, (((addr >> 1) & 0x7) << 9) | (1 << 8) | (3 << 12) | 1);
++#ifdef PEDANTIC_OCTASIC_CHECKING
++ while((__t4_raw_oct_in(wc, 0x0000) & (1 << 8)) && --count);
++ if (count != 1000)
++ dev_notice(&wc->dev->dev, "Yah, write can be slow\n");
++ if (!count)
++ dev_notice(&wc->dev->dev, "Write timed out!\n");
++#endif
++}
++
++static inline void t4_oct_out(struct t4 *wc, const unsigned int addr, const unsigned int value)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&wc->reglock, flags);
++ __t4_oct_out(wc, addr, value);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++}
++
++static inline void t4_vpm_out(struct t4 *wc, int unit, const unsigned int addr, const unsigned int value)
++{
++ unsigned long flags;
++ spin_lock_irqsave(&wc->reglock, flags);
++ __t4_vpm_out(wc, unit, addr, value);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++}
++
++static const char vpm_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', '*', '#'};
++
++static void t4_check_vpm450(struct t4 *wc)
++{
++ int channel, tone, start, span;
++
++ if (vpm450m_checkirq(wc->vpm450m)) {
++ while(vpm450m_getdtmf(wc->vpm450m, &channel, &tone, &start)) {
++ span = channel & 0x3;
++ channel >>= 2;
++ if (!wc->t1e1)
++ channel -= 5;
++ else
++ channel -= 1;
++ if (unlikely(debug))
++ dev_info(&wc->dev->dev, "Got tone %s of '%c' "
++ "on channel %d of span %d\n",
++ (start ? "START" : "STOP"),
++ tone, channel, span + 1);
++ if (test_bit(channel, &wc->tspans[span]->dtmfmask) && (tone != 'u')) {
++ if (start) {
++ /* The octasic is supposed to mute us, but... Yah, you
++ guessed it. */
++ if (test_bit(channel, &wc->tspans[span]->dtmfmutemask)) {
++ unsigned long flags;
++ struct dahdi_chan *chan = wc->tspans[span]->span.chans[channel];
++ int y;
++ spin_lock_irqsave(&chan->lock, flags);
++ for (y=0;y<chan->numbufs;y++) {
++ if ((chan->inreadbuf > -1) && (chan->readidx[y]))
++ memset(chan->readbuf[chan->inreadbuf], DAHDI_XLAW(0, chan), chan->readidx[y]);
++ }
++ spin_unlock_irqrestore(&chan->lock, flags);
++ }
++ set_bit(channel, &wc->tspans[span]->dtmfactive);
++ dahdi_qevent_lock(wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFDOWN | tone));
++ } else {
++ clear_bit(channel, &wc->tspans[span]->dtmfactive);
++ dahdi_qevent_lock(wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFUP | tone));
++ }
++ }
++ }
++ }
++}
++
++static void t4_check_vpm400(struct t4 *wc, unsigned int newio)
++{
++ unsigned int digit, regval = 0;
++ unsigned int regbyte;
++ int x, i;
++ short energy=0;
++ static unsigned int lastio = 0;
++ struct t4_span *ts;
++
++ if (debug && (newio != lastio))
++ dev_notice(&wc->dev->dev, "Last was %08x, new is %08x\n",
++ lastio, newio);
++
++ lastio = newio;
++
++ for(x = 0; x < 8; x++) {
++ if (newio & (1 << (7 - x)))
++ continue;
++ ts = wc->tspans[x%4];
++ /* Start of DTMF detection process */
++ regbyte = t4_vpm_in(wc, x, 0xb8);
++ t4_vpm_out(wc, x, 0xb8, regbyte); /* Write 1 to clear */
++ regval = regbyte << 8;
++ regbyte = t4_vpm_in(wc, x, 0xb9);
++ t4_vpm_out(wc, x, 0xb9, regbyte);
++ regval |= regbyte;
++
++ for(i = 0; (i < MAX_DTMF_DET) && regval; i++) {
++ if(regval & 0x0001) {
++ int channel = (i << 1) + (x >> 2);
++ int base = channel - 1;
++
++ if (!wc->t1e1)
++ base -= 4;
++ regbyte = t4_vpm_in(wc, x, 0xa8 + i);
++ digit = vpm_digits[regbyte];
++ if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN)) {
++ energy = t4_vpm_in(wc, x, 0x58 + channel);
++ energy = DAHDI_XLAW(energy, ts->chans[0]);
++ ts->dtmfenergy[base] = energy;
++ }
++ set_bit(base, &ts->dtmfactive);
++ if (ts->dtmfdigit[base]) {
++ if (ts->dtmfmask & (1 << base))
++ dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
++ }
++ ts->dtmfdigit[base] = digit;
++ if (test_bit(base, &ts->dtmfmask))
++ dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFDOWN | digit));
++ if (test_bit(base, &ts->dtmfmutemask)) {
++ /* Mute active receive buffer*/
++ unsigned long flags;
++ struct dahdi_chan *chan = ts->span.chans[base];
++ int y;
++ spin_lock_irqsave(&chan->lock, flags);
++ for (y=0;y<chan->numbufs;y++) {
++ if ((chan->inreadbuf > -1) && (chan->readidx[y]))
++ memset(chan->readbuf[chan->inreadbuf], DAHDI_XLAW(0, chan), chan->readidx[y]);
++ }
++ spin_unlock_irqrestore(&chan->lock, flags);
++ }
++ if (debug)
++ dev_notice(&wc->dev->dev, "Digit "
++ "Seen: %d, Span: %d, channel:"
++ " %d, energy: %02x, 'channel "
++ "%d' chip %d\n", digit, x % 4,
++ base + 1, energy, channel, x);
++
++ }
++ regval = regval >> 1;
++ }
++ if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN))
++ continue;
++
++ /* Start of DTMF off detection process */
++ regbyte = t4_vpm_in(wc, x, 0xbc);
++ t4_vpm_out(wc, x, 0xbc, regbyte); /* Write 1 to clear */
++ regval = regbyte << 8;
++ regbyte = t4_vpm_in(wc, x, 0xbd);
++ t4_vpm_out(wc, x, 0xbd, regbyte);
++ regval |= regbyte;
++
++ for(i = 0; (i < MAX_DTMF_DET) && regval; i++) {
++ if(regval & 0x0001) {
++ int channel = (i << 1) + (x >> 2);
++ int base = channel - 1;
++
++ if (!wc->t1e1)
++ base -= 4;
++ clear_bit(base, &ts->dtmfactive);
++ if (ts->dtmfdigit[base]) {
++ if (test_bit(base, &ts->dtmfmask))
++ dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
++ }
++ digit = ts->dtmfdigit[base];
++ ts->dtmfdigit[base] = 0;
++ if (debug)
++ dev_notice(&wc->dev->dev, "Digit "
++ "Gone: %d, Span: %d, channel:"
++ " %d, energy: %02x, 'channel "
++ "%d' chip %d\n", digit, x % 4,
++ base + 1, energy, channel, x);
++
++ }
++ regval = regval >> 1;
++ }
++
++ }
++}
++#endif
++
++static void hdlc_stop(struct t4 *wc, unsigned int span)
++{
++ struct t4_span *t = wc->tspans[span];
++ unsigned char imr0, imr1, mode;
++ int i = 0;
++
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "Stopping HDLC controller on span "
++ "%d\n", span+1);
++
++ /* Clear receive and transmit timeslots */
++ for (i = 0; i < 4; i++) {
++ t4_framer_out(wc, span, FRMR_RTR_BASE + i, 0x00);
++ t4_framer_out(wc, span, FRMR_TTR_BASE + i, 0x00);
++ }
++
++ imr0 = t4_framer_in(wc, span, FRMR_IMR0);
++ imr1 = t4_framer_in(wc, span, FRMR_IMR1);
++
++ /* Disable HDLC interrupts */
++ imr0 |= HDLC_IMR0_MASK;
++ t4_framer_out(wc, span, FRMR_IMR0, imr0);
++
++ imr1 |= HDLC_IMR1_MASK;
++ t4_framer_out(wc, span, FRMR_IMR1, imr1);
++
++ mode = t4_framer_in(wc, span, FRMR_MODE);
++ mode &= ~FRMR_MODE_HRAC;
++ t4_framer_out(wc, span, FRMR_MODE, mode);
++
++ t->sigactive = 0;
++}
++
++static inline void __t4_framer_cmd(struct t4 *wc, unsigned int span, int cmd)
++{
++ __t4_framer_out(wc, span, FRMR_CMDR, cmd);
++}
++
++static inline void t4_framer_cmd_wait(struct t4 *wc, unsigned int span, int cmd)
++{
++ int sis;
++ int loops = 0;
++
++ /* XXX could be time consuming XXX */
++ for (;;) {
++ sis = t4_framer_in(wc, span, FRMR_SIS);
++ if (!(sis & 0x04))
++ break;
++ if (!loops++ && (debug & DEBUG_FRAMER)) {
++ dev_notice(&wc->dev->dev, "!!!SIS Waiting before cmd "
++ "%02x\n", cmd);
++ }
++ }
++ if (loops && (debug & DEBUG_FRAMER))
++ dev_notice(&wc->dev->dev, "!!!SIS waited %d loops\n", loops);
++
++ t4_framer_out(wc, span, FRMR_CMDR, cmd);
++}
++
++static int hdlc_start(struct t4 *wc, unsigned int span, struct dahdi_chan *chan, unsigned char mode)
++{
++ struct t4_span *t = wc->tspans[span];
++ unsigned char imr0, imr1;
++ int offset = chan->chanpos;
++ unsigned long flags;
++
++ if (debug & DEBUG_FRAMER)
++ dev_info(&wc->dev->dev, "Starting HDLC controller for channel "
++ "%d span %d\n", offset, span+1);
++
++ if (mode != FRMR_MODE_NO_ADDR_CMP)
++ return -1;
++
++ mode |= FRMR_MODE_HRAC;
++
++ /* Make sure we're in the right mode */
++ t4_framer_out(wc, span, FRMR_MODE, mode);
++ t4_framer_out(wc, span, FRMR_TSEO, 0x00);
++ t4_framer_out(wc, span, FRMR_TSBS1, hardhdlcmode);
++
++ /* Set the interframe gaps, etc */
++ t4_framer_out(wc, span, FRMR_CCR1, FRMR_CCR1_ITF|FRMR_CCR1_EITS);
++
++ t4_framer_out(wc, span, FRMR_CCR2, FRMR_CCR2_RCRC);
++
++ /* Set up the time slot that we want to tx/rx on */
++ t4_framer_out(wc, span, FRMR_TTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
++ t4_framer_out(wc, span, FRMR_RTR_BASE + (offset / 8), (0x80 >> (offset % 8)));
++
++ imr0 = t4_framer_in(wc, span, FRMR_IMR0);
++ imr1 = t4_framer_in(wc, span, FRMR_IMR1);
++
++ /* Enable our interrupts again */
++ imr0 &= ~HDLC_IMR0_MASK;
++ t4_framer_out(wc, span, FRMR_IMR0, imr0);
++
++ imr1 &= ~HDLC_IMR1_MASK;
++ t4_framer_out(wc, span, FRMR_IMR1, imr1);
++
++ /* Reset the signaling controller */
++ t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
++
++ spin_lock_irqsave(&wc->reglock, flags);
++ t->sigchan = chan;
++ spin_unlock_irqrestore(&wc->reglock, flags);
++
++ t->sigactive = 0;
++
++ return 0;
++}
++
++static void __set_clear(struct t4 *wc, int span)
++{
++ int i,j;
++ int oldnotclear;
++ unsigned short val=0;
++ struct t4_span *ts = wc->tspans[span];
++
++ oldnotclear = ts->notclear;
++ if ((ts->spantype == TYPE_T1) || (ts->spantype == TYPE_J1)) {
++ for (i=0;i<24;i++) {
++ j = (i/8);
++ if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR) {
++ val |= 1 << (7 - (i % 8));
++ ts->notclear &= ~(1 << i);
++ } else
++ ts->notclear |= (1 << i);
++ if ((i % 8)==7) {
++ if (debug)
++ dev_notice(&wc->dev->dev, "Putting %d "
++ "in register %02x on span %d"
++ "\n", val, 0x2f + j, span + 1);
++ __t4_framer_out(wc, span, 0x2f + j, val);
++ val = 0;
++ }
++ }
++ } else {
++ for (i=0;i<31;i++) {
++ if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
++ ts->notclear &= ~(1 << i);
++ else
++ ts->notclear |= (1 << i);
++ }
++ }
++ if (ts->notclear != oldnotclear) {
++ unsigned char reg;
++ reg = __t4_framer_in(wc, span, FRMR_IMR0);
++ if (ts->notclear)
++ reg &= ~0x08;
++ else
++ reg |= 0x08;
++ __t4_framer_out(wc, span, FRMR_IMR0, reg);
++ }
++}
++
++#if 0
++static void set_clear(struct t4 *wc, int span)
++{
++ unsigned long flags;
++ spin_lock_irqsave(&wc->reglock, flags);
++ __set_clear(wc, span);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++}
++#endif
++
++static int t4_dacs(struct dahdi_chan *dst, struct dahdi_chan *src)
++{
++ struct t4 *wc;
++ struct t4_span *ts;
++ wc = dst->pvt;
++ ts = wc->tspans[dst->span->offset];
++ if (src && (src->pvt != dst->pvt)) {
++ if (ts->spanflags & FLAG_2NDGEN)
++ t4_tsi_unassign(wc, dst->span->offset, dst->chanpos);
++ wc = src->pvt;
++ if (ts->spanflags & FLAG_2NDGEN)
++ t4_tsi_unassign(wc, src->span->offset, src->chanpos);
++ if (debug)
++ dev_notice(&wc->dev->dev, "Unassigning %d/%d by "
++ "default and...\n", src->span->offset,
++ src->chanpos);
++ if (debug)
++ dev_notice(&wc->dev->dev, "Unassigning %d/%d by "
++ "default\n", dst->span->offset, dst->chanpos);
++ return -1;
++ }
++ if (src) {
++ t4_tsi_assign(wc, src->span->offset, src->chanpos, dst->span->offset, dst->chanpos);
++ if (debug)
++ dev_notice(&wc->dev->dev, "Assigning channel %d/%d -> "
++ "%d/%d!\n", src->span->offset, src->chanpos,
++ dst->span->offset, dst->chanpos);
++ } else {
++ t4_tsi_unassign(wc, dst->span->offset, dst->chanpos);
++ if (debug)
++ dev_notice(&wc->dev->dev, "Unassigning channel %d/%d!"
++ "\n", dst->span->offset, dst->chanpos);
++ }
++ return 0;
++}
++
++#ifdef VPM_SUPPORT
++
++void oct_set_reg(void *data, unsigned int reg, unsigned int val)
++{
++ struct t4 *wc = data;
++ t4_oct_out(wc, reg, val);
++}
++
++unsigned int oct_get_reg(void *data, unsigned int reg)
++{
++ struct t4 *wc = data;
++ unsigned int ret;
++ ret = t4_oct_in(wc, reg);
++ return ret;
++}
++
++static int t4_vpm_unit(int span, int channel)
++{
++ int unit = 0;
++ switch(vpmspans) {
++ case 4:
++ unit = span;
++ unit += (channel & 1) << 2;
++ break;
++ case 2:
++ unit = span;
++ unit += (channel & 0x3) << 1;
++ break;
++ case 1:
++ unit = span;
++ unit += (channel & 0x7);
++ }
++ return unit;
++}
++
++static inline struct t4_span *t4_from_span(struct dahdi_span *span)
++{
++ return container_of(span, struct t4_span, span);
++}
++
++static int t4_echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
++ struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
++{
++ struct t4 *wc = chan->pvt;
++ struct t4_span *tspan = container_of(chan->span, struct t4_span, span);
++ int channel;
++ const struct dahdi_echocan_ops *ops;
++ const struct dahdi_echocan_features *features;
++
++ if (!vpmsupport || !wc->vpm)
++ return -ENODEV;
++
++ if (chan->span->offset >= vpmspans)
++ return -ENODEV;
++
++ if (wc->vpm450m) {
++ ops = &vpm450m_ec_ops;
++ features = &vpm450m_ec_features;
++ } else {
++ ops = &vpm400m_ec_ops;
++ features = &vpm400m_ec_features;
++ }
++
++ if (ecp->param_count > 0) {
++ dev_warn(&wc->dev->dev, "echo canceller does not support "
++ "parameters; failing request\n");
++ return -EINVAL;
++ }
++
++ *ec = tspan->ec[chan->chanpos - 1];
++ (*ec)->ops = ops;
++ (*ec)->features = *features;
++
++ channel = wc->t1e1 ? chan->chanpos : chan->chanpos + 4;
++
++ if (wc->vpm450m) {
++ channel = channel << 2;
++ channel |= chan->span->offset;
++ if (debug & DEBUG_ECHOCAN)
++ dev_notice(&wc->dev->dev, "echocan: Card is %d, "
++ "Channel is %d, Span is %d, offset is %d "
++ "length %d\n", wc->num, chan->chanpos,
++ chan->span->offset, channel, ecp->tap_length);
++ vpm450m_setec(wc->vpm450m, channel, ecp->tap_length);
++ } else {
++ int unit = t4_vpm_unit(chan->span->offset, channel);
++
++ if (debug & DEBUG_ECHOCAN)
++ dev_notice(&wc->dev->dev, "echocan: Card is %d, "
++ "Channel is %d, Span is %d, unit is %d, "
++ "unit offset is %d length %d\n", wc->num,
++ chan->chanpos, chan->span->offset, unit,
++ channel, ecp->tap_length);
++ t4_vpm_out(wc, unit, channel, 0x3e);
++ }
++
++ return 0;
++}
++
++static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec)
++{
++ struct t4 *wc = chan->pvt;
++ int channel;
++
++ memset(ec, 0, sizeof(*ec));
++
++ channel = wc->t1e1 ? chan->chanpos : chan->chanpos + 4;
++
++ if (wc->vpm450m) {
++ channel = channel << 2;
++ channel |= chan->span->offset;
++ if (debug & DEBUG_ECHOCAN)
++ dev_notice(&wc->dev->dev, "echocan: Card is %d, "
++ "Channel is %d, Span is %d, offset is %d "
++ "length 0\n", wc->num, chan->chanpos,
++ chan->span->offset, channel);
++ vpm450m_setec(wc->vpm450m, channel, 0);
++ } else {
++ int unit = t4_vpm_unit(chan->span->offset, channel);
++
++ if (debug & DEBUG_ECHOCAN)
++ dev_notice(&wc->dev->dev, "echocan: Card is %d, "
++ "Channel is %d, Span is %d, unit is %d, "
++ "unit offset is %d length 0\n", wc->num,
++ chan->chanpos, chan->span->offset, unit,
++ channel);
++ t4_vpm_out(wc, unit, channel, 0x01);
++ }
++}
++#endif
++
++static int t4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
++{
++ struct t4_regs regs;
++ int x;
++ struct t4 *wc = chan->pvt;
++#ifdef VPM_SUPPORT
++ int j;
++ int channel;
++ struct t4_span *ts = wc->tspans[chan->span->offset];
++#endif
++
++#ifdef VPM_SUPPORT
++ if (dtmfthreshold == 0)
++ dtmfthreshold = VPM_DEFAULT_DTMFTHRESHOLD;
++ if (lastdtmfthreshold != dtmfthreshold) {
++ lastdtmfthreshold = dtmfthreshold;
++ t4_vpm_set_dtmf_threshold(wc, dtmfthreshold);
++ }
++#endif
++
++ switch(cmd) {
++ case WCT4_GET_REGS:
++ for (x=0;x<NUM_PCI;x++)
++ regs.pci[x] = t4_pci_in(wc, x);
++ for (x=0;x<NUM_REGS;x++)
++ regs.regs[x] = t4_framer_in(wc, chan->span->offset, x);
++ if (copy_to_user((__user void *) data, &regs, sizeof(regs)))
++ return -EFAULT;
++ break;
++#ifdef VPM_SUPPORT
++ case DAHDI_TONEDETECT:
++ if (get_user(j, (__user int *) data))
++ return -EFAULT;
++ if (!wc->vpm)
++ return -ENOSYS;
++ if (j && (vpmdtmfsupport == 0))
++ return -ENOSYS;
++ if (j & DAHDI_TONEDETECT_ON)
++ set_bit(chan->chanpos - 1, &ts->dtmfmask);
++ else
++ clear_bit(chan->chanpos - 1, &ts->dtmfmask);
++ if (j & DAHDI_TONEDETECT_MUTE)
++ set_bit(chan->chanpos - 1, &ts->dtmfmutemask);
++ else
++ clear_bit(chan->chanpos - 1, &ts->dtmfmutemask);
++ if (wc->vpm450m) {
++ channel = (chan->chanpos) << 2;
++ if (!wc->t1e1)
++ channel += (4 << 2);
++ channel |= chan->span->offset;
++ vpm450m_setdtmf(wc->vpm450m, channel, j & DAHDI_TONEDETECT_ON, j & DAHDI_TONEDETECT_MUTE);
++ }
++ return 0;
++#endif
++ default:
++ return -ENOTTY;
++ }
++ return 0;
++}
++
++static void inline t4_hdlc_xmit_fifo(struct t4 *wc, unsigned int span, struct t4_span *ts)
++{
++ int res, i;
++ unsigned int size = 32;
++ unsigned char buf[32];
++
++ res = dahdi_hdlc_getbuf(ts->sigchan, buf, &size);
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "Got buffer sized %d and res %d "
++ "for %d\n", size, res, span);
++ if (size > 0) {
++ ts->sigactive = 1;
++
++ if (debug & DEBUG_FRAMER) {
++ dev_notice(&wc->dev->dev, "TX(");
++ for (i = 0; i < size; i++)
++ dev_notice(&wc->dev->dev, "%s%02x",
++ (i ? " " : ""), buf[i]);
++ dev_notice(&wc->dev->dev, ")\n");
++ }
++
++ for (i = 0; i < size; i++)
++ t4_framer_out(wc, span, FRMR_TXFIFO, buf[i]);
++
++ if (res) /* End of message */ {
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev,
++ "transmiting XHF|XME\n");
++ t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF | FRMR_CMDR_XME);
++#if 0
++ ts->sigactive = (__t4_framer_in(wc, span, FRMR_SIS) & FRMR_SIS_XFW) ? 0 : 1;
++#endif
++ ++ts->frames_out;
++ if ((debug & DEBUG_FRAMER) && !(ts->frames_out & 0x0f))
++ dev_notice(&wc->dev->dev, "Transmitted %d "
++ "frames on span %d\n", ts->frames_out,
++ span);
++ } else { /* Still more to transmit */
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "transmiting XHF\n");
++ t4_framer_cmd_wait(wc, span, FRMR_CMDR_XHF);
++ }
++ }
++ else if (res < 0)
++ ts->sigactive = 0;
++}
++
++static void t4_hdlc_hard_xmit(struct dahdi_chan *chan)
++{
++ struct t4 *wc = chan->pvt;
++ int span = chan->span->offset;
++ struct t4_span *ts = wc->tspans[span];
++ unsigned long flags;
++
++ spin_lock_irqsave(&wc->reglock, flags);
++ if (!ts->sigchan) {
++ dev_notice(&wc->dev->dev, "t4_hdlc_hard_xmit: Invalid (NULL) "
++ "signalling channel\n");
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ return;
++ }
++ spin_unlock_irqrestore(&wc->reglock, flags);
++
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "t4_hdlc_hard_xmit on channel %s "
++ "(sigchan %s), sigactive=%d\n", chan->name,
++ ts->sigchan->name, ts->sigactive);
++
++ if ((ts->sigchan == chan) && !ts->sigactive)
++ t4_hdlc_xmit_fifo(wc, span, ts);
++}
++
++static int t4_maint(struct dahdi_span *span, int cmd)
++{
++ struct t4_span *ts = t4_from_span(span);
++ struct t4 *wc = ts->owner;
++ unsigned int reg;
++#ifdef DAHDI_SPAN_OPS
++ unsigned long flags;
++#endif
++
++ if (ts->spantype == TYPE_E1) {
++ switch(cmd) {
++ case DAHDI_MAINT_NONE:
++ dev_info(&wc->dev->dev, "Clearing all maint modes\n");
++ t4_clear_maint(span);
++ break;
++ case DAHDI_MAINT_LOCALLOOP:
++ dev_info(&wc->dev->dev,
++ "Turning on local loopback\n");
++ t4_clear_maint(span);
++ reg = t4_framer_in(wc, span->offset, LIM0_T);
++ t4_framer_out(wc, span->offset, LIM0_T, (reg|LIM0_LL));
++ break;
++#ifdef DAHDI_SPAN_OPS
++ case DAHDI_MAINT_NETWORKLINELOOP:
++ dev_info(&wc->dev->dev,
++ "Turning on network line loopback\n");
++ t4_clear_maint(span);
++ reg = t4_framer_in(wc, span->offset, LIM1_T);
++ t4_framer_out(wc, span->offset, LIM1_T, (reg|LIM1_RL));
++ break;
++ case DAHDI_MAINT_NETWORKPAYLOADLOOP:
++ dev_info(&wc->dev->dev,
++ "Turning on network payload loopback\n");
++ t4_clear_maint(span);
++ reg = t4_framer_in(wc, span->offset, FMR2_T);
++ t4_framer_out(wc, span->offset, FMR2_T, (reg|FMR2_PLB));
++ break;
++#endif
++ case DAHDI_MAINT_LOOPUP:
++ case DAHDI_MAINT_LOOPDOWN:
++ dev_info(&wc->dev->dev,
++ "Loopup & loopdown supported in E1 mode\n");
++ return -ENOSYS;
++#ifdef DAHDI_SPAN_OPS
++ case DAHDI_MAINT_FAS_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, IFASE);
++ break;
++ case DAHDI_MAINT_MULTI_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, IMFE);
++ break;
++ case DAHDI_MAINT_CRC_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, ICRCE);
++ break;
++ case DAHDI_MAINT_CAS_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, ICASE);
++ break;
++ case DAHDI_MAINT_PRBS_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, IPE);
++ break;
++ case DAHDI_MAINT_BIPOLAR_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, IBV);
++ break;
++ case DAHDI_RESET_COUNTERS:
++ t4_reset_counters(span);
++ break;
++ case DAHDI_MAINT_ALARM_SIM:
++ dev_info(&wc->dev->dev, "Invoking alarm state");
++ reg = t4_framer_in(wc, span->offset, FMR0);
++ t4_framer_out(wc, span->offset, FMR0, (reg|FMR0_SIM));
++ break;
++#endif
++ default:
++ dev_info(&wc->dev->dev,
++ "Unknown E1 maint command: %d\n", cmd);
++ return -ENOSYS;
++ }
++ } else {
++ switch(cmd) {
++ case DAHDI_MAINT_NONE:
++ dev_info(&wc->dev->dev, "Clearing all maint modes\n");
++ t4_clear_maint(span);
++ break;
++ case DAHDI_MAINT_LOCALLOOP:
++ dev_info(&wc->dev->dev,
++ "Turning on local loopback\n");
++ t4_clear_maint(span);
++ reg = t4_framer_in(wc, span->offset, LIM0_T);
++ t4_framer_out(wc, span->offset, LIM0_T, (reg|LIM0_LL));
++ break;
++#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
++ case DAHDI_MAINT_NETWORKLINELOOP:
++ dev_info(&wc->dev->dev,
++ "Turning on network line loopback\n");
++ t4_clear_maint(span);
++ reg = t4_framer_in(wc, span->offset, LIM1_T);
++ t4_framer_out(wc, span->offset, LIM1_T, (reg|LIM1_RL));
++ break;
++ case DAHDI_MAINT_NETWORKPAYLOADLOOP:
++ dev_info(&wc->dev->dev,
++ "Turning on network payload loopback\n");
++ t4_clear_maint(span);
++ reg = t4_framer_in(wc, span->offset, FMR2_T);
++ t4_framer_out(wc, span->offset, FMR2_T, (reg|FMR2_PLB));
++ break;
++#endif
++ case DAHDI_MAINT_LOOPUP:
++ dev_info(&wc->dev->dev, "Transmitting loopup code\n");
++ t4_clear_maint(span);
++ t4_framer_out(wc, span->offset, 0x21, 0x50);
++ break;
++ case DAHDI_MAINT_LOOPDOWN:
++ dev_info(&wc->dev->dev, "Transmitting loopdown code\n");
++ t4_clear_maint(span);
++ t4_framer_out(wc, span->offset, 0x21, 0x60);
++ break;
++#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
++ case DAHDI_MAINT_FAS_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, IFASE);
++ break;
++ case DAHDI_MAINT_MULTI_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, IMFE);
++ break;
++ case DAHDI_MAINT_CRC_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, ICRCE);
++ break;
++ case DAHDI_MAINT_CAS_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, ICASE);
++ break;
++ case DAHDI_MAINT_PRBS_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, IPE);
++ break;
++ case DAHDI_MAINT_BIPOLAR_DEFECT:
++ t4_framer_out(wc, span->offset, IERR_T, IBV);
++ break;
++ case DAHDI_MAINT_PRBS:
++ dev_info(&wc->dev->dev, "PRBS not supported\n");
++#if 0
++ dev_notice(&wc->dev->dev, "Enabling PRBS!\n");
++ span->mainttimer = 1;
++ /* Enable PRBS monitor */
++ reg = t4_framer_in(wc, span->offset, LCR1_T);
++ reg |= EPRM;
++
++ /* Setup PRBS xmit */
++ t4_framer_out(wc, span->offset, TPC0_T, 0);
++
++ /* Enable PRBS transmit */
++ reg |= XPRBS;
++ reg &= ~LLBP;
++ reg &= ~FLLB;
++ t4_framer_out(wc, span->offset, LCR1_T, reg);
++#endif
++ return -ENOSYS;
++ case DAHDI_RESET_COUNTERS:
++ t4_reset_counters(span);
++ break;
++#endif
++#ifdef DAHDI_SPAN_OPS
++ case DAHDI_MAINT_ALARM_SIM:
++ reg = t4_framer_in(wc, span->offset, FMR0);
++
++ /*
++ * The alarm simulation state machine requires us to
++ * bring this bit up and down for at least 1 clock cycle
++ */
++ spin_lock_irqsave(&wc->reglock, flags);
++ __t4_framer_out(wc, span->offset,
++ FMR0, (reg | FMR0_SIM));
++ udelay(1);
++ __t4_framer_out(wc, span->offset,
++ FMR0, (reg & ~FMR0_SIM));
++ udelay(1);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++
++ reg = t4_framer_in(wc, span->offset, 0x4e);
++ if (debug & DEBUG_MAIN) {
++ dev_info(&wc->dev->dev,
++ "FRS2(alarm state): %d\n",
++ ((reg & 0xe0) >> 5));
++ }
++ break;
++#endif
++ default:
++ dev_info(&wc->dev->dev, "Unknown T1 maint command:%d\n",
++ cmd);
++ break;
++ }
++ }
++ return 0;
++}
++
++static int t4_clear_maint(struct dahdi_span *span)
++{
++ struct t4_span *ts = t4_from_span(span);
++ struct t4 *wc = ts->owner;
++ unsigned int reg;
++
++ /* Clear local loop */
++ reg = t4_framer_in(wc, span->offset, LIM0_T);
++ t4_framer_out(wc, span->offset, LIM0_T, (reg & ~LIM0_LL));
++
++ /* Clear Remote Loop */
++ reg = t4_framer_in(wc, span->offset, LIM1_T);
++ t4_framer_out(wc, span->offset, LIM1_T, (reg & ~LIM1_RL));
++
++ /* Clear Remote Payload Loop */
++ reg = t4_framer_in(wc, span->offset, FMR2_T);
++ t4_framer_out(wc, span->offset, FMR2_T, (reg & ~FMR2_PLB));
++
++ /* Clear PRBS */
++ reg = t4_framer_in(wc, span->offset, LCR1_T);
++ t4_framer_out(wc, span->offset, LCR1_T, (reg & ~(XPRBS | EPRM)));
++
++ span->mainttimer = 0;
++
++ return 0;
++}
++
++#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
++static int t4_reset_counters(struct dahdi_span *span)
++{
++ struct t4_span *ts = t4_from_span(span);
++ memset(&ts->span.count, 0, sizeof(ts->span.count));
++ return 0;
++}
++#endif
++
++static int t4_rbsbits(struct dahdi_chan *chan, int bits)
++{
++ u_char m,c;
++ int k,n,b;
++ struct t4 *wc = chan->pvt;
++ struct t4_span *ts = wc->tspans[chan->span->offset];
++ unsigned long flags;
++
++ if (debug & DEBUG_RBS)
++ dev_notice(&wc->dev->dev, "Setting bits to %d on channel %s\n",
++ bits, chan->name);
++ spin_lock_irqsave(&wc->reglock, flags);
++ k = chan->span->offset;
++ if (ts->spantype == TYPE_E1) { /* do it E1 way */
++ if (chan->chanpos == 16) {
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ return 0;
++ }
++ n = chan->chanpos - 1;
++ if (chan->chanpos > 15) n--;
++ b = (n % 15);
++ c = ts->txsigs[b];
++ m = (n / 15) << 2; /* nibble selector */
++ c &= (0xf << m); /* keep the other nibble */
++ c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
++ ts->txsigs[b] = c;
++ /* output them to the chip */
++ __t4_framer_out(wc,k,0x71 + b,c);
++ } else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
++ n = chan->chanpos - 1;
++ b = (n/4);
++ c = ts->txsigs[b];
++ m = ((3 - (n % 4)) << 1); /* nibble selector */
++ c &= ~(0x3 << m); /* keep the other nibble */
++ c |= ((bits >> 2) & 0x3) << m; /* put our new nibble here */
++ ts->txsigs[b] = c;
++ /* output them to the chip */
++ __t4_framer_out(wc,k,0x70 + b,c);
++ __t4_framer_out(wc,k,0x70 + b + 6,c);
++ } else if (ts->span.lineconfig & DAHDI_CONFIG_ESF) {
++ n = chan->chanpos - 1;
++ b = (n/2);
++ c = ts->txsigs[b];
++ m = ((n % 2) << 2); /* nibble selector */
++ c &= (0xf << m); /* keep the other nibble */
++ c |= (bits & 0xf) << (4 - m); /* put our new nibble here */
++ ts->txsigs[b] = c;
++ /* output them to the chip */
++ __t4_framer_out(wc,k,0x70 + b,c);
++ }
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ if (debug & DEBUG_RBS)
++ dev_notice(&wc->dev->dev, "Finished setting RBS bits\n");
++ return 0;
++}
++
++static int t4_shutdown(struct dahdi_span *span)
++{
++ int tspan;
++ int wasrunning;
++ unsigned long flags;
++ struct t4_span *ts = t4_from_span(span);
++ struct t4 *wc = ts->owner;
++
++ tspan = span->offset + 1;
++ if (tspan < 0) {
++ dev_notice(&wc->dev->dev, "opvxd115: Span '%d' isn't us?\n",
++ span->spanno);
++ return -1;
++ }
++
++ if (debug & DEBUG_MAIN)
++ dev_notice(&wc->dev->dev, "Shutting down span %d (%s)\n",
++ span->spanno, span->name);
++
++ /* Stop HDLC controller if runned */
++ if (ts->sigchan)
++ hdlc_stop(wc, span->offset);
++
++ spin_lock_irqsave(&wc->reglock, flags);
++ wasrunning = span->flags & DAHDI_FLAG_RUNNING;
++
++ span->flags &= ~DAHDI_FLAG_RUNNING;
++ __t4_set_led(wc, span->offset, WC_OFF);
++ if ((wc->numspans == 1) &&
++ (!(wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING))) {
++ /* No longer in use, disable interrupts */
++ dev_info(&wc->dev->dev, "opvxd115: Disabling interrupts since "
++ "there are no active spans\n");
++ set_bit(T4_STOP_DMA, &wc->checkflag);
++ } else
++ set_bit(T4_CHECK_TIMING, &wc->checkflag);
++
++ spin_unlock_irqrestore(&wc->reglock, flags);
++
++ /* Wait for interrupt routine to shut itself down */
++ msleep(10);
++ if (wasrunning)
++ wc->spansstarted--;
++
++ if (debug & DEBUG_MAIN)
++ dev_notice(&wc->dev->dev, "Span %d (%s) shutdown\n",
++ span->spanno, span->name);
++ return 0;
++}
++
++static void t4_chan_set_sigcap(struct dahdi_span *span, int x)
++{
++ struct t4_span *wc = container_of(span, struct t4_span, span);
++ struct dahdi_chan *chan = wc->chans[x];
++ chan->sigcap = DAHDI_SIG_CLEAR;
++ /* E&M variant supported depends on span type */
++ if (wc->spantype == TYPE_E1) {
++ /* E1 sigcap setup */
++ if (span->lineconfig & DAHDI_CONFIG_CCS) {
++ /* CCS setup */
++ chan->sigcap |= DAHDI_SIG_MTP2 | DAHDI_SIG_SF |
++ DAHDI_SIG_HARDHDLC;
++ return;
++ }
++ /* clear out sig and sigcap for channel 16 on E1 CAS
++ * lines, otherwise, set it correctly */
++ if (x == 15) {
++ /* CAS signaling channel setup */
++ wc->chans[15]->sigcap = 0;
++ wc->chans[15]->sig = 0;
++ return;
++ }
++ /* normal CAS setup */
++ chan->sigcap |= DAHDI_SIG_EM_E1 | DAHDI_SIG_FXSLS |
++ DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_SF |
++ DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS |
++ DAHDI_SIG_CAS | DAHDI_SIG_DACS_RBS;
++ } else {
++ /* T1 sigcap setup */
++ chan->sigcap |= DAHDI_SIG_EM | DAHDI_SIG_FXSLS |
++ DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_MTP2 |
++ DAHDI_SIG_SF | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS |
++ DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_DACS_RBS |
++ DAHDI_SIG_HARDHDLC;
++ }
++}
++
++static int t4_spanconfig(struct file *file, struct dahdi_span *span,
++ struct dahdi_lineconfig *lc)
++{
++ int i;
++ struct t4_span *ts = t4_from_span(span);
++ struct t4 *wc = ts->owner;
++
++ if (debug)
++ dev_info(&wc->dev->dev, "About to enter spanconfig!\n");
++ if (debug & DEBUG_MAIN)
++ dev_notice(&wc->dev->dev, "opvxd115: Configuring span %d\n",
++ span->spanno);
++
++ if (lc->sync < 0)
++ lc->sync = 0;
++ if (lc->sync > wc->numspans)
++ lc->sync = 0;
++
++ /* remove this span number from the current sync sources, if there */
++ for(i = 0; i < wc->numspans; i++) {
++ if (wc->tspans[i]->sync == span->spanno) {
++ wc->tspans[i]->sync = 0;
++ wc->tspans[i]->psync = 0;
++ }
++ }
++ wc->tspans[span->offset]->syncpos = lc->sync;
++ /* if a sync src, put it in proper place */
++ if (lc->sync) {
++ wc->tspans[lc->sync - 1]->sync = span->spanno;
++ wc->tspans[lc->sync - 1]->psync = span->offset + 1;
++ }
++ set_bit(T4_CHECK_TIMING, &wc->checkflag);
++
++ /* Make sure this is clear in case of multiple startup and shutdown
++ * iterations */
++ clear_bit(T4_STOP_DMA, &wc->checkflag);
++
++ /* make sure that sigcaps gets updated if necessary */
++ for (i = 0; i < span->channels; i++)
++ t4_chan_set_sigcap(span, i);
++
++ /* If we're already running, then go ahead and apply the changes */
++ if (span->flags & DAHDI_FLAG_RUNNING)
++ return t4_startup(file, span);
++
++ if (debug)
++ dev_info(&wc->dev->dev, "Done with spanconfig!\n");
++ return 0;
++}
++
++static int t4_chanconfig(struct file *file, struct dahdi_chan *chan,
++ int sigtype)
++{
++ int alreadyrunning;
++ unsigned long flags;
++ struct t4 *wc = chan->pvt;
++ struct t4_span *ts = wc->tspans[chan->span->offset];
++
++ alreadyrunning = ts->span.flags & DAHDI_FLAG_RUNNING;
++ if (debug & DEBUG_MAIN) {
++ if (alreadyrunning)
++ dev_notice(&wc->dev->dev, "opvxd115: Reconfigured "
++ "channel %d (%s) sigtype %d\n",
++ chan->channo, chan->name, sigtype);
++ else
++ dev_notice(&wc->dev->dev, "opvxd115: Configured channel"
++ " %d (%s) sigtype %d\n",
++ chan->channo, chan->name, sigtype);
++ }
++
++ spin_lock_irqsave(&wc->reglock, flags);
++
++ if (alreadyrunning)
++ __set_clear(wc, chan->span->offset);
++
++ spin_unlock_irqrestore(&wc->reglock, flags);
++
++ /* (re)configure signalling channel */
++ if ((sigtype == DAHDI_SIG_HARDHDLC) || (ts->sigchan == chan)) {
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "%sonfiguring hardware HDLC "
++ "on %s\n",
++ ((sigtype == DAHDI_SIG_HARDHDLC) ? "C" : "Unc"),
++ chan->name);
++ if (alreadyrunning) {
++ if (ts->sigchan)
++ hdlc_stop(wc, ts->sigchan->span->offset);
++ if (sigtype == DAHDI_SIG_HARDHDLC) {
++ if (hdlc_start(wc, chan->span->offset, chan, ts->sigmode)) {
++ dev_notice(&wc->dev->dev, "Error "
++ "initializing signalling "
++ "controller\n");
++ return -1;
++ }
++ } else {
++ spin_lock_irqsave(&wc->reglock, flags);
++ ts->sigchan = NULL;
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ }
++
++ }
++ else {
++ spin_lock_irqsave(&wc->reglock, flags);
++ ts->sigchan = (sigtype == DAHDI_SIG_HARDHDLC) ? chan : NULL;
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ ts->sigactive = 0;
++ }
++ }
++ return 0;
++}
++
++static int t4_open(struct dahdi_chan *chan)
++{
++ return 0;
++}
++
++static int t4_close(struct dahdi_chan *chan)
++{
++ return 0;
++}
++
++static void set_span_devicetype(struct t4 *wc)
++{
++ struct dahdi_device *ddev = wc->ddev;
++ const char *devicetype_old = ddev->devicetype;
++ char *extra_str = "";
++
++ if (wc->vpm == T4_VPM_PRESENT)
++ extra_str = (!wc->vpm450m) ? " (VPM400M)" : " (VPMOCT032)",
++ wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s%s",
++ wc->variety, extra_str);
++
++ /* On the off chance that we were able to allocate it previously. */
++ if (!wc->ddev->devicetype)
++ wc->ddev->devicetype = devicetype_old;
++ else
++ kfree(devicetype_old);
++}
++
++/* The number of cards we have seen with each
++ possible 'order' switch setting.
++*/
++static unsigned int order_index[16];
++
++static void setup_chunks(struct t4 *wc, int which)
++{
++ struct t4_span *ts;
++ int offset = 1;
++ int x, y;
++ int gen2;
++
++ if (!wc->t1e1)
++ offset += 4;
++
++ gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
++
++ for (x = 0; x < wc->numspans; x++) {
++ ts = wc->tspans[x];
++ ts->writechunk = (void *)(wc->writechunk + (x * 32 * 2) + (which * (1024 >> 2)));
++ ts->readchunk = (void *)(wc->readchunk + (x * 32 * 2) + (which * (1024 >> 2)));
++ for (y=0;y<wc->tspans[x]->span.channels;y++) {
++ struct dahdi_chan *mychans = ts->chans[y];
++ if (gen2) {
++ mychans->writechunk = (void *)(wc->writechunk + ((x * 32 + y + offset) * 2) + (which * (1024 >> 2)));
++ mychans->readchunk = (void *)(wc->readchunk + ((x * 32 + y + offset) * 2) + (which * (1024 >> 2)));
++ }
++ }
++ }
++}
++
++#ifdef DAHDI_SPAN_OPS
++static const struct dahdi_span_ops t4_gen1_span_ops = {
++ .owner = THIS_MODULE,
++ .spanconfig = t4_spanconfig,
++ .chanconfig = t4_chanconfig,
++ .startup = t4_startup,
++ .shutdown = t4_shutdown,
++ .rbsbits = t4_rbsbits,
++ .maint = t4_maint,
++ .open = t4_open,
++ .close = t4_close,
++ .ioctl = t4_ioctl,
++ .hdlc_hard_xmit = t4_hdlc_hard_xmit,
++};
++
++static const struct dahdi_span_ops t4_gen2_span_ops = {
++ .owner = THIS_MODULE,
++ .spanconfig = t4_spanconfig,
++ .chanconfig = t4_chanconfig,
++ .startup = t4_startup,
++ .shutdown = t4_shutdown,
++ .rbsbits = t4_rbsbits,
++ .maint = t4_maint,
++ .open = t4_open,
++ .close = t4_close,
++ .ioctl = t4_ioctl,
++ .hdlc_hard_xmit = t4_hdlc_hard_xmit,
++ .dacs = t4_dacs,
++#ifdef VPM_SUPPORT
++ .echocan_create = t4_echocan_create,
++#endif
++};
++#endif
++
++static void init_spans(struct t4 *wc)
++{
++ int x,y;
++ int gen2;
++ struct t4_span *ts;
++ unsigned int reg;
++
++ wc->ddev->manufacturer = "OpenVox";
++ if (order_index[wc->order] == 1)
++ wc->ddev->location = kasprintf(GFP_KERNEL,
++ "Board ID Switch %d", wc->order);
++ else
++ wc->ddev->location = kasprintf(GFP_KERNEL,
++ "PCI Bus %02d Slot %02d",
++ wc->dev->bus->number,
++ PCI_SLOT(wc->dev->devfn) + 1);
++ if (!wc->ddev->location)
++ return; /* FIXME: Error handling */
++
++ gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
++ for (x = 0; x < wc->numspans; x++) {
++ ts = wc->tspans[x];
++ sprintf(ts->span.name, "D115/D130/%d/%d", wc->num, x + 1);
++ snprintf(ts->span.desc, sizeof(ts->span.desc) - 1,
++ "D115/D130 (E1|T1) Card %d Span %d", wc->num, x+1);
++ switch (ts->spantype) {
++ case TYPE_T1:
++ ts->span.spantype = SPANTYPE_DIGITAL_T1;
++ break;
++ case TYPE_E1:
++ ts->span.spantype = SPANTYPE_DIGITAL_E1;
++ break;
++ case TYPE_J1:
++ ts->span.spantype = SPANTYPE_DIGITAL_J1;
++ break;
++ }
++#ifdef DAHDI_SPAN_MODULE
++ ts->span.owner = THIS_MODULE;
++#endif
++#ifdef DAHDI_SPAN_OPS
++ if (gen2) {
++ ts->span.ops = &t4_gen2_span_ops;
++ } else {
++ ts->span.ops = &t4_gen1_span_ops;
++ }
++#else
++ ts->span.spanconfig = t4_spanconfig;
++ ts->span.chanconfig = t4_chanconfig;
++ ts->span.startup = t4_startup;
++ ts->span.shutdown = t4_shutdown;
++ ts->span.rbsbits = t4_rbsbits;
++ ts->span.maint = t4_maint;
++ ts->span.open = t4_open;
++ ts->span.close = t4_close;
++ ts->span.ioctl = t4_ioctl;
++ ts->span.hdlc_hard_xmit = t4_hdlc_hard_xmit;
++ if (gen2) {
++#ifdef VPM_SUPPORT
++ if (vpmsupport)
++ ts->span.echocan_create = t4_echocan_create;
++#endif
++ ts->span.dacs = t4_dacs;
++ }
++ ts->span.pvt = ts;
++#endif
++
++ /* HDLC Specific init */
++ ts->sigchan = NULL;
++ ts->sigmode = sigmode;
++ ts->sigactive = 0;
++
++ if (ts->spantype == TYPE_T1 || ts->spantype == TYPE_J1) {
++ ts->span.channels = 24;
++ ts->span.deflaw = DAHDI_LAW_MULAW;
++ ts->span.linecompat = DAHDI_CONFIG_AMI |
++ DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 |
++ DAHDI_CONFIG_ESF;
++ } else {
++ ts->span.channels = 31;
++ ts->span.deflaw = DAHDI_LAW_ALAW;
++ ts->span.linecompat = DAHDI_CONFIG_AMI |
++ DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS |
++ DAHDI_CONFIG_CRC4;
++ }
++ ts->span.chans = ts->chans;
++ ts->span.flags = DAHDI_FLAG_RBS;
++
++ ts->owner = wc;
++ ts->span.offset = x;
++ ts->writechunk = (void *)(wc->writechunk + x * 32 * 2);
++ ts->readchunk = (void *)(wc->readchunk + x * 32 * 2);
++
++ for (y=0;y<wc->tspans[x]->span.channels;y++) {
++ struct dahdi_chan *mychans = ts->chans[y];
++ sprintf(mychans->name, "D115/D130/%d/%d/%d", wc->num, x + 1, y + 1);
++ t4_chan_set_sigcap(&ts->span, x);
++ mychans->pvt = wc;
++ mychans->chanpos = y + 1;
++ }
++
++ /* Enable 1sec timer interrupt */
++ reg = t4_framer_in(wc, x, FMR1_T);
++ t4_framer_out(wc, x, FMR1_T, (reg | FMR1_ECM));
++
++ /* Enable Errored Second interrupt */
++ t4_framer_out(wc, x, ESM, 0);
++
++#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
++ t4_reset_counters(&ts->span);
++#endif
++ }
++
++ set_span_devicetype(wc);
++ setup_chunks(wc, 0);
++ wc->lastindex = 0;
++}
++
++static void t4_serial_setup(struct t4 *wc, int unit)
++{
++ if (!wc->globalconfig) {
++ wc->globalconfig = 1;
++ if (debug)
++ dev_info(&wc->dev->dev, "opvxd115: Setting up global "
++ "serial parameters\n");
++ t4_framer_out(wc, 0, 0x85, 0xe0); /* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from channel 0 */
++ t4_framer_out(wc, 0, 0x08, 0x01); /* IPC: Interrupt push/pull active low */
++
++ /* Global clocks (8.192 Mhz CLK) */
++ t4_framer_out(wc, 0, 0x92, 0x00);
++ t4_framer_out(wc, 0, 0x93, 0x18);
++ t4_framer_out(wc, 0, 0x94, 0xfb);
++ t4_framer_out(wc, 0, 0x95, 0x0b);
++ t4_framer_out(wc, 0, 0x96, 0x00);
++ t4_framer_out(wc, 0, 0x97, 0x0b);
++ t4_framer_out(wc, 0, 0x98, 0xdb);
++ t4_framer_out(wc, 0, 0x99, 0xdf);
++ }
++
++ /* Configure interrupts */
++ t4_framer_out(wc, unit, FRMR_GCR, 0x00); /* GCR: Interrupt on Activation/Deactivation of each */
++
++ /* Configure system interface */
++ t4_framer_out(wc, unit, FRMR_SIC1, 0xc2); /* SIC1: 8.192 Mhz clock/bus, double buffer receive / transmit, byte interleaved */
++ t4_framer_out(wc, unit, FRMR_SIC2, 0x20 | (unit << 1)); /* SIC2: No FFS, no center receive eliastic buffer, phase */
++ t4_framer_out(wc, unit, FRMR_SIC3, 0x04); /* SIC3: Edges for capture */
++ t4_framer_out(wc, unit, FRMR_CMR2, 0x00); /* CMR2: We provide sync and clock for tx and rx. */
++ if (!wc->t1e1) { /* T1 mode */
++ t4_framer_out(wc, unit, FRMR_XC0, 0x03); /* XC0: Normal operation of Sa-bits */
++ t4_framer_out(wc, unit, FRMR_XC1, 0x84); /* XC1: 0 offset */
++ if (wc->tspans[unit]->spantype == TYPE_J1)
++ t4_framer_out(wc, unit, FRMR_RC0, 0x83); /* RC0: Just shy of 1023 */
++ else
++ t4_framer_out(wc, unit, FRMR_RC0, 0x03); /* RC0: Just shy of 1023 */
++ t4_framer_out(wc, unit, FRMR_RC1, 0x84); /* RC1: The rest of RC0 */
++ } else { /* E1 mode */
++ t4_framer_out(wc, unit, FRMR_XC0, 0x00); /* XC0: Normal operation of Sa-bits */
++ t4_framer_out(wc, unit, FRMR_XC1, 0x04); /* XC1: 0 offset */
++ t4_framer_out(wc, unit, FRMR_RC0, 0x04); /* RC0: Just shy of 1023 */
++ t4_framer_out(wc, unit, FRMR_RC1, 0x04); /* RC1: The rest of RC0 */
++ }
++
++ /* Configure ports */
++ t4_framer_out(wc, unit, 0x80, 0x00); /* PC1: SPYR/SPYX input on RPA/XPA */
++ if (wc->falc31) {
++ t4_framer_out(wc, unit, 0x81, 0xBB); /* PC2: RMFB/XSIG output/input on RPB/XPB */
++ t4_framer_out(wc, unit, 0x82, 0xBB); /* PC3: Some unused stuff */
++ t4_framer_out(wc, unit, 0x83, 0xBB); /* PC4: Some more unused stuff */
++ } else {
++ t4_framer_out(wc, unit, 0x81, 0x22); /* PC2: RMFB/XSIG output/input on RPB/XPB */
++ t4_framer_out(wc, unit, 0x82, 0x65); /* PC3: Some unused stuff */
++ t4_framer_out(wc, unit, 0x83, 0x35); /* PC4: Some more unused stuff */
++ }
++ t4_framer_out(wc, unit, 0x84, 0x01); /* PC5: XMFS active low, SCLKR is input, RCLK is output */
++ if (debug & DEBUG_MAIN)
++ dev_notice(&wc->dev->dev, "Successfully initialized serial "
++ "bus for unit %d\n", unit);
++}
++
++static int syncsrc = 0;
++static int syncnum = 0 /* -1 */;
++static int syncspan = 0;
++#ifdef DEFINE_SPINLOCK
++static DEFINE_SPINLOCK(synclock);
++#else
++static spinlock_t synclock = SPIN_LOCK_UNLOCKED;
++#endif
++
++static void __t4_set_rclk_src(struct t4 *wc, int span)
++{
++ int cmr1 = 0x38; /* Clock Mode: RCLK sourced by DCO-R1
++ by default, Disable Clock-Switching */
++
++ cmr1 |= (span << 6);
++ __t4_framer_out(wc, 0, 0x44, cmr1);
++
++ dev_info(&wc->dev->dev, "RCLK source set to span %d\n", span+1);
++}
++
++static void __t4_set_sclk_src(struct t4 *wc, int mode, int master, int slave)
++{
++ if (slave) {
++ wc->dmactrl |= (1 << 25);
++ dev_info(&wc->dev->dev, "SCLK is slaved to timing cable\n");
++ } else {
++ wc->dmactrl &= ~(1 << 25);
++ }
++
++ if (master) {
++ wc->dmactrl |= (1 << 24);
++ dev_info(&wc->dev->dev, "SCLK is master to timing cable\n");
++ } else {
++ wc->dmactrl &= ~(1 << 24);
++ }
++
++ if (mode == WC_RECOVER)
++ wc->dmactrl |= (1 << 29); /* Recover timing from RCLK */
++
++ if (mode == WC_SELF)
++ wc->dmactrl &= ~(1 << 29);/* Provide timing from MCLK */
++
++ __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++}
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18))
++static ssize_t t4_timing_master_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct t4 *wc = dev_get_drvdata(dev);
++ if (wc->dmactrl & (1 << 29))
++ return sprintf(buf, "%d\n", wc->syncsrc);
++ else
++ return sprintf(buf, "%d\n", -1);
++}
++
++static DEVICE_ATTR(timing_master, 0400, t4_timing_master_show, NULL);
++
++static void create_sysfs_files(struct t4 *wc)
++{
++ int ret;
++ ret = device_create_file(&wc->dev->dev,
++ &dev_attr_timing_master);
++ if (ret) {
++ dev_info(&wc->dev->dev,
++ "Failed to create device attributes.\n");
++ }
++}
++
++static void remove_sysfs_files(struct t4 *wc)
++{
++ device_remove_file(&wc->dev->dev,
++ &dev_attr_timing_master);
++}
++
++#else
++
++static inline void create_sysfs_files(struct t4 *wc) { return; }
++static inline void remove_sysfs_files(struct t4 *wc) { return; }
++
++#endif /* LINUX_KERNEL > 2.6.18 */
++
++static inline void __t4_update_timing(struct t4 *wc)
++{
++ int i;
++ /* update sync src info */
++ if (wc->syncsrc != syncsrc) {
++ dev_info(&wc->dev->dev, "Swapping card %d from %d to %d\n",
++ wc->num, wc->syncsrc, syncsrc);
++ wc->syncsrc = syncsrc;
++ /* Update sync sources */
++ for (i = 0; i < wc->numspans; i++) {
++ wc->tspans[i]->span.syncsrc = wc->syncsrc;
++ }
++ if (syncnum == wc->num) {
++ __t4_set_rclk_src(wc, syncspan-1);
++ __t4_set_sclk_src(wc, WC_RECOVER, 1, 0);
++ if (debug)
++ dev_notice(&wc->dev->dev, "Card %d, using sync "
++ "span %d, master\n", wc->num, syncspan);
++ } else {
++ __t4_set_sclk_src(wc, WC_RECOVER, 0, 1);
++ if (debug)
++ dev_notice(&wc->dev->dev, "Card %d, using "
++ "Timing Bus, NOT master\n", wc->num);
++ }
++ }
++}
++
++static int __t4_findsync(struct t4 *wc)
++{
++ int i;
++ int x;
++ unsigned long flags;
++ int p;
++ int nonzero;
++ int newsyncsrc = 0; /* DAHDI span number */
++ int newsyncnum = 0; /* opvxd115 card number */
++ int newsyncspan = 0; /* span on given opvxd115 card */
++ spin_lock_irqsave(&synclock, flags);
++#if 1
++ if (!wc->num) {
++ /* If we're the first card, go through all the motions, up to 8 levels
++ of sync source */
++ p = 1;
++ while (p < 8) {
++ nonzero = 0;
++ for (x=0;cards[x];x++) {
++ for (i = 0; i < wc->numspans; i++) {
++ if (cards[x]->tspans[i]->syncpos) {
++ nonzero = 1;
++ if ((cards[x]->tspans[i]->syncpos == p) &&
++ !(cards[x]->tspans[i]->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_LOOPBACK)) &&
++ (cards[x]->tspans[i]->span.flags & DAHDI_FLAG_RUNNING)) {
++ /* This makes a good sync source */
++ newsyncsrc = cards[x]->tspans[i]->span.spanno;
++ newsyncnum = x;
++ newsyncspan = i + 1;
++ /* Jump out */
++ goto found;
++ }
++ }
++ }
++ }
++ if (nonzero)
++ p++;
++ else
++ break;
++ }
++found:
++ if ((syncnum != newsyncnum) || (syncsrc != newsyncsrc) || (newsyncspan != syncspan)) {
++ if (debug)
++ dev_notice(&wc->dev->dev, "New syncnum: %d "
++ "(was %d), syncsrc: %d (was %d), "
++ "syncspan: %d (was %d)\n", newsyncnum,
++ syncnum, newsyncsrc, syncsrc,
++ newsyncspan, syncspan);
++ syncnum = newsyncnum;
++ syncsrc = newsyncsrc;
++ syncspan = newsyncspan;
++ for (x=0;cards[x];x++) {
++ __t4_update_timing(cards[x]);
++ }
++ }
++ }
++ __t4_update_timing(wc);
++#endif
++ spin_unlock_irqrestore(&synclock, flags);
++ return 0;
++}
++
++static void __t4_set_timing_source_auto(struct t4 *wc)
++{
++ int x;
++ int firstprio, secondprio;
++ firstprio = secondprio = 4;
++
++ if (debug)
++ dev_info(&wc->dev->dev, "timing source auto\n");
++ clear_bit(T4_CHECK_TIMING, &wc->checkflag);
++ if (timingcable) {
++ __t4_findsync(wc);
++ } else {
++ if (debug)
++ dev_info(&wc->dev->dev, "Evaluating spans for timing "
++ "source\n");
++ for (x=0;x<wc->numspans;x++) {
++ if ((wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) &&
++ !(wc->tspans[x]->span.alarms & (DAHDI_ALARM_RED |
++ DAHDI_ALARM_BLUE))) {
++ if (debug)
++ dev_info(&wc->dev->dev, "span %d is "
++ "green : syncpos %d\n", x+1,
++ wc->tspans[x]->syncpos);
++ if (wc->tspans[x]->syncpos) {
++ /* Valid rsync source in recovered
++ timing mode */
++ if (firstprio == 4)
++ firstprio = x;
++ else if (wc->tspans[x]->syncpos <
++ wc->tspans[firstprio]->syncpos)
++ firstprio = x;
++ } else {
++ /* Valid rsync source in system timing
++ mode */
++ if (secondprio == 4)
++ secondprio = x;
++ }
++ }
++ }
++ if (firstprio != 4) {
++ wc->syncsrc = firstprio;
++ __t4_set_rclk_src(wc, firstprio);
++ __t4_set_sclk_src(wc, WC_RECOVER, 0, 0);
++ dev_info(&wc->dev->dev, "Recovered timing mode, "\
++ "RCLK set to span %d\n",
++ firstprio+1);
++ } else if (secondprio != 4) {
++ wc->syncsrc = -1;
++ __t4_set_rclk_src(wc, secondprio);
++ __t4_set_sclk_src(wc, WC_SELF, 0, 0);
++ dev_info(&wc->dev->dev, "System timing mode, "\
++ "RCLK set to span %d\n",
++ secondprio+1);
++ } else {
++ wc->syncsrc = -1;
++ dev_info(&wc->dev->dev, "All spans in alarm : No valid"\
++ "span to source RCLK from\n");
++ /* Default rclk to lock with span 1 */
++ __t4_set_rclk_src(wc, 0);
++ __t4_set_sclk_src(wc, WC_SELF, 0, 0);
++ }
++ }
++}
++
++static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlevel)
++{
++ unsigned int fmr4, fmr2, fmr1, fmr0, lim2;
++ char *framing, *line;
++ int mytxlevel;
++ if ((txlevel > 7) || (txlevel < 4))
++ mytxlevel = 0;
++ else
++ mytxlevel = txlevel - 4;
++ fmr1 = 0x9c; /* FMR1: Mode 1, T1 mode, CRC on for ESF, 8.192 Mhz system data rate, no XAIS */
++ fmr2 = 0x20; /* FMR2: no payload loopback, don't auto yellow */
++ fmr4 = 0x0c; /* FMR4: Lose sync on 2 out of 5 framing bits, auto resync */
++ lim2 = 0x21; /* LIM2: 50% peak is a "1", Advanced Loss recovery */
++ lim2 |= (mytxlevel << 6); /* LIM2: Add line buildout */
++ __t4_framer_out(wc, unit, 0x1d, fmr1);
++ __t4_framer_out(wc, unit, 0x1e, fmr2);
++
++ /* Configure line interface */
++ if (lineconfig & DAHDI_CONFIG_AMI) {
++ line = "AMI";
++ /* workaround for errata #2 in ES v3 09-10-16 */
++ fmr0 = (wc->falc31) ? 0xb0 : 0xa0;
++ } else {
++ line = "B8ZS";
++ fmr0 = 0xf0;
++ }
++ if (lineconfig & DAHDI_CONFIG_D4) {
++ framing = "D4";
++ } else {
++ framing = "ESF";
++ fmr4 |= 0x2;
++ fmr2 |= 0xc0;
++ }
++ __t4_framer_out(wc, unit, 0x1c, fmr0);
++ __t4_framer_out(wc, unit, 0x20, fmr4);
++ __t4_framer_out(wc, unit, 0x21, 0x40); /* FMR5: Enable RBS mode */
++
++ __t4_framer_out(wc, unit, 0x37, 0xf0 ); /* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */
++ __t4_framer_out(wc, unit, 0x36, 0x08); /* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */
++
++ __t4_framer_out(wc, unit, 0x02, 0x50); /* CMDR: Reset the receiver and transmitter line interface */
++ __t4_framer_out(wc, unit, 0x02, 0x00); /* CMDR: Reset the receiver and transmitter line interface */
++
++ if (wc->falc31) {
++ if (debug)
++ dev_info(&wc->dev->dev, "card %d span %d: setting Rtx "
++ "to 0ohm for T1\n", wc->num, unit);
++ __t4_framer_out(wc, unit, 0x86, 0x00); /* PC6: set Rtx to 0ohm for T1 */
++
++ // Hitting the bugfix register to fix errata #3
++ __t4_framer_out(wc, unit, 0xbd, 0x05);
++ }
++
++ __t4_framer_out(wc, unit, 0x3a, lim2); /* LIM2: 50% peak amplitude is a "1" */
++ __t4_framer_out(wc, unit, 0x38, 0x0a); /* PCD: LOS after 176 consecutive "zeros" */
++ __t4_framer_out(wc, unit, 0x39, 0x15); /* PCR: 22 "ones" clear LOS */
++
++ /* Generate pulse mask for T1 */
++ switch(mytxlevel) {
++ case 3:
++ __t4_framer_out(wc, unit, 0x26, 0x07); /* XPM0 */
++ __t4_framer_out(wc, unit, 0x27, 0x01); /* XPM1 */
++ __t4_framer_out(wc, unit, 0x28, 0x00); /* XPM2 */
++ break;
++ case 2:
++ __t4_framer_out(wc, unit, 0x26, 0x8c); /* XPM0 */
++ __t4_framer_out(wc, unit, 0x27, 0x11); /* XPM1 */
++ __t4_framer_out(wc, unit, 0x28, 0x01); /* XPM2 */
++ break;
++ case 1:
++ __t4_framer_out(wc, unit, 0x26, 0x8c); /* XPM0 */
++ __t4_framer_out(wc, unit, 0x27, 0x01); /* XPM1 */
++ __t4_framer_out(wc, unit, 0x28, 0x00); /* XPM2 */
++ break;
++ case 0:
++ default:
++ __t4_framer_out(wc, unit, 0x26, 0xd7); /* XPM0 */
++ __t4_framer_out(wc, unit, 0x27, 0x22); /* XPM1 */
++ __t4_framer_out(wc, unit, 0x28, 0x01); /* XPM2 */
++ break;
++ }
++
++ /* Don't mask framer interrupts if hardware HDLC is in use */
++ __t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0)); /* IMR0: We care about CAS changes, etc */
++ __t4_framer_out(wc, unit, FRMR_IMR1, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0)); /* IMR1: We care about nothing */
++ __t4_framer_out(wc, unit, 0x16, 0x00); /* IMR2: All the alarm stuff! */
++ __t4_framer_out(wc, unit, 0x17, 0x34); /* IMR3: AIS and friends */
++ __t4_framer_out(wc, unit, 0x18, 0x3f); /* IMR4: Slips on transmit */
++
++ dev_info(&wc->dev->dev, "Span %d configured for %s/%s\n", unit + 1,
++ framing, line);
++}
++
++static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
++{
++ unsigned int fmr2, fmr1, fmr0;
++ unsigned int cas = 0;
++ unsigned int imr3extra=0;
++ char *crc4 = "";
++ char *framing, *line;
++ fmr1 = 0x44; /* FMR1: E1 mode, Automatic force resync, PCM30 mode, 8.192 Mhz backplane, no XAIS */
++ fmr2 = 0x03; /* FMR2: Auto transmit remote alarm, auto loss of multiframe recovery, no payload loopback */
++ if (lineconfig & DAHDI_CONFIG_CRC4) {
++ fmr1 |= 0x08; /* CRC4 transmit */
++ fmr2 |= 0xc0; /* CRC4 receive */
++ crc4 = "/CRC4";
++ }
++ __t4_framer_out(wc, unit, 0x1d, fmr1);
++ __t4_framer_out(wc, unit, 0x1e, fmr2);
++
++ /* Configure line interface */
++ if (lineconfig & DAHDI_CONFIG_AMI) {
++ line = "AMI";
++ /* workaround for errata #2 in ES v3 09-10-16 */
++ fmr0 = (wc->falc31) ? 0xb0 : 0xa0;
++ } else {
++ line = "HDB3";
++ fmr0 = 0xf0;
++ }
++ if (lineconfig & DAHDI_CONFIG_CCS) {
++ framing = "CCS";
++ imr3extra = 0x28;
++ } else {
++ framing = "CAS";
++ cas = 0x40;
++ }
++ __t4_framer_out(wc, unit, 0x1c, fmr0);
++
++ __t4_framer_out(wc, unit, 0x37, 0xf0 /*| 0x6 */ ); /* LIM1: Clear data in case of LOS, Set receiver threshold (0.5V), No remote loop, no DRS */
++ __t4_framer_out(wc, unit, 0x36, 0x08); /* LIM0: Enable auto long haul mode, no local loop (must be after LIM1) */
++
++ __t4_framer_out(wc, unit, 0x02, 0x50); /* CMDR: Reset the receiver and transmitter line interface */
++ __t4_framer_out(wc, unit, 0x02, 0x00); /* CMDR: Reset the receiver and transmitter line interface */
++
++ if (wc->falc31) {
++ if (debug)
++ dev_info(&wc->dev->dev,
++ "setting Rtx to 7.5ohm for E1\n");
++ __t4_framer_out(wc, unit, 0x86, 0x40); /* PC6: turn on 7.5ohm Rtx for E1 */
++ }
++
++ /* Condition receive line interface for E1 after reset */
++ __t4_framer_out(wc, unit, 0xbb, 0x17);
++ __t4_framer_out(wc, unit, 0xbc, 0x55);
++ __t4_framer_out(wc, unit, 0xbb, 0x97);
++ __t4_framer_out(wc, unit, 0xbb, 0x11);
++ __t4_framer_out(wc, unit, 0xbc, 0xaa);
++ __t4_framer_out(wc, unit, 0xbb, 0x91);
++ __t4_framer_out(wc, unit, 0xbb, 0x12);
++ __t4_framer_out(wc, unit, 0xbc, 0x55);
++ __t4_framer_out(wc, unit, 0xbb, 0x92);
++ __t4_framer_out(wc, unit, 0xbb, 0x0c);
++ __t4_framer_out(wc, unit, 0xbb, 0x00);
++ __t4_framer_out(wc, unit, 0xbb, 0x8c);
++
++ __t4_framer_out(wc, unit, 0x3a, 0x20); /* LIM2: 50% peak amplitude is a "1" */
++ __t4_framer_out(wc, unit, 0x38, 0x0a); /* PCD: LOS after 176 consecutive "zeros" */
++ __t4_framer_out(wc, unit, 0x39, 0x15); /* PCR: 22 "ones" clear LOS */
++
++ __t4_framer_out(wc, unit, 0x20, 0x9f); /* XSW: Spare bits all to 1 */
++ __t4_framer_out(wc, unit, 0x21, 0x1c|cas); /* XSP: E-bit set when async. AXS auto, XSIF to 1 */
++
++
++ /* Generate pulse mask for E1 */
++ __t4_framer_out(wc, unit, 0x26, 0x54); /* XPM0 */
++ __t4_framer_out(wc, unit, 0x27, 0x02); /* XPM1 */
++ __t4_framer_out(wc, unit, 0x28, 0x00); /* XPM2 */
++
++ /* Don't mask framer interrupts if hardware HDLC is in use */
++ __t4_framer_out(wc, unit, FRMR_IMR0, 0xff & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR0_MASK : 0)); /* IMR0: We care about CRC errors, CAS changes, etc */
++ __t4_framer_out(wc, unit, FRMR_IMR1, 0x3f & ~((wc->tspans[unit]->sigchan) ? HDLC_IMR1_MASK : 0)); /* IMR1: We care about loopup / loopdown */
++ __t4_framer_out(wc, unit, 0x16, 0x00); /* IMR2: We care about all the alarm stuff! */
++ __t4_framer_out(wc, unit, 0x17, 0x04 | imr3extra); /* IMR3: AIS */
++ __t4_framer_out(wc, unit, 0x18, 0x3f); /* IMR4: We care about slips on transmit */
++
++ dev_info(&wc->dev->dev, "opvxd115: Span %d configured for %s/%s%s\n",
++ unit + 1, framing, line, crc4);
++}
++
++static int t4_startup(struct file *file, struct dahdi_span *span)
++{
++#ifdef SUPPORT_GEN1
++ int i;
++#endif
++ int tspan;
++ unsigned long flags;
++ int alreadyrunning;
++ struct t4_span *ts = t4_from_span(span);
++ struct t4 *wc = ts->owner;
++
++ set_bit(T4_IGNORE_LATENCY, &wc->checkflag);
++ if (debug)
++ dev_info(&wc->dev->dev, "About to enter startup!\n");
++ tspan = span->offset + 1;
++ if (tspan < 0) {
++ dev_info(&wc->dev->dev, "opvxd115: Span '%d' isn't us?\n",
++ span->spanno);
++ return -1;
++ }
++
++ spin_lock_irqsave(&wc->reglock, flags);
++
++ alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
++
++#ifdef SUPPORT_GEN1
++ /* initialize the start value for the entire chunk of last ec buffer */
++ for(i = 0; i < span->channels; i++)
++ {
++ memset(ts->ec_chunk1[i],
++ DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
++ memset(ts->ec_chunk2[i],
++ DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
++ }
++#endif
++ /* Force re-evaluation of timing source */
++ wc->syncsrc = -1;
++ set_bit(T4_CHECK_TIMING, &wc->checkflag);
++
++ if (ts->spantype == TYPE_E1) { /* if this is an E1 card */
++ __t4_configure_e1(wc, span->offset, span->lineconfig);
++ } else { /* is a T1 card */
++ __t4_configure_t1(wc, span->offset, span->lineconfig, span->txlevel);
++ }
++
++ /* Note clear channel status */
++ wc->tspans[span->offset]->notclear = 0;
++ __set_clear(wc, span->offset);
++
++ if (!alreadyrunning) {
++ span->flags |= DAHDI_FLAG_RUNNING;
++ wc->spansstarted++;
++
++ if (wc->flags & FLAG_5THGEN)
++ __t4_pci_out(wc, 5, (ms_per_irq << 16) | wc->numbufs);
++ /* enable interrupts */
++ /* Start DMA, enabling DMA interrupts on read only */
++#if 0
++ /* Enable framer only interrupts */
++ wc->dmactrl |= 1 << 27;
++#endif
++ wc->dmactrl |= (ts->spanflags & FLAG_2NDGEN) ? 0xc0000000 : 0xc0000003;
++#ifdef VPM_SUPPORT
++ wc->dmactrl |= wc->vpm;
++#endif
++ /* Seed interrupt register */
++ __t4_pci_out(wc, WC_INTR, 0x0c);
++ if (noburst || !(ts->spanflags & FLAG_BURST))
++ wc->dmactrl |= (1 << 26);
++ __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++
++ /* Startup HDLC controller too */
++ }
++
++ if (ts->sigchan) {
++ struct dahdi_chan *sigchan = ts->sigchan;
++
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ if (hdlc_start(wc, span->offset, sigchan, ts->sigmode)) {
++ dev_notice(&wc->dev->dev, "Error initializing "
++ "signalling controller\n");
++ return -1;
++ }
++ spin_lock_irqsave(&wc->reglock, flags);
++ }
++
++ spin_unlock_irqrestore(&wc->reglock, flags);
++
++ t4_check_alarms(wc, span->offset);
++ t4_check_sigbits(wc, span->offset);
++
++ if (wc->tspans[0]->sync == span->spanno)
++ dev_info(&wc->dev->dev, "SPAN %d: Primary Sync Source\n",
++ span->spanno);
++#ifdef VPM_SUPPORT
++ if (!alreadyrunning && !wc->vpm) {
++ wait_a_little();
++ t4_vpm400_init(wc);
++ if (!wc->vpm)
++ t4_vpm450_init(wc);
++ wc->dmactrl |= wc->vpm;
++ t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++ if (wc->vpm)
++ set_span_devicetype(wc);
++ }
++#endif
++ if (debug)
++ dev_info(&wc->dev->dev, "Completed startup!\n");
++ clear_bit(T4_IGNORE_LATENCY, &wc->checkflag);
++ return 0;
++}
++
++#ifdef SUPPORT_GEN1
++static inline void e1_check(struct t4 *wc, int span, int val)
++{
++ struct t4_span *ts = wc->tspans[span];
++ if ((ts->span.channels > 24) &&
++ (ts->span.flags & DAHDI_FLAG_RUNNING) &&
++ !(ts->span.alarms) &&
++ (!wc->e1recover)) {
++ if (val != 0x1b) {
++ ts->e1check++;
++ } else
++ ts->e1check = 0;
++ if (ts->e1check > 100) {
++ /* Wait 1000 ms */
++ wc->e1recover = 1000 * 8;
++ wc->tspans[0]->e1check = 0;
++ if (debug & DEBUG_MAIN)
++ dev_notice(&wc->dev->dev, "Detected loss of "
++ "E1 alignment on span %d!\n", span);
++ t4_reset_dma(wc);
++ }
++ }
++}
++
++static void t4_receiveprep(struct t4 *wc, int irq)
++{
++ volatile unsigned int *readchunk;
++ int dbl = 0;
++ int x,y,z;
++ unsigned int tmp;
++ int offset=0;
++ if (!wc->t1e1)
++ offset = 4;
++ if (irq & 1) {
++ /* First part */
++ readchunk = wc->readchunk;
++ if (!wc->last0)
++ dbl = 1;
++ wc->last0 = 0;
++ } else {
++ readchunk = wc->readchunk + DAHDI_CHUNKSIZE * 32;
++ if (wc->last0)
++ dbl = 1;
++ wc->last0 = 1;
++ }
++ if (dbl) {
++ for (x=0;x<wc->numspans;x++)
++ wc->ddev->irqmisses++;
++ if (debug & DEBUG_MAIN)
++ dev_notice(&wc->dev->dev, "opvxd115: Double/missed "
++ "interrupt detected\n");
++ }
++ for (x=0;x<DAHDI_CHUNKSIZE;x++) {
++ for (z=0;z<24;z++) {
++ /* All T1/E1 channels */
++ tmp = readchunk[z+1+offset];
++ wc->tspans[0]->span.chans[z]->readchunk[x] = tmp >> 24;
++ }
++ if (wc->t1e1) {
++ if (wc->e1recover > 0)
++ wc->e1recover--;
++ tmp = readchunk[0];
++ e1_check(wc, 0, (tmp & 0x7f000000) >> 24);
++ for (z=24;z<31;z++) {
++ /* Only E1 channels now */
++ tmp = readchunk[z+1];
++ if (wc->tspans[0]->span.channels > 24)
++ wc->tspans[0]->span.chans[z]->readchunk[x] = tmp >> 24;
++ }
++ }
++ /* Advance pointer by 4 TDM frame lengths */
++ readchunk += 32;
++ }
++ for (x=0;x<wc->numspans;x++) {
++ if (wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) {
++ for (y=0;y<wc->tspans[x]->span.channels;y++) {
++ /* Echo cancel double buffered data */
++ dahdi_ec_chunk(wc->tspans[x]->span.chans[y],
++ wc->tspans[x]->span.chans[y]->readchunk,
++ wc->tspans[x]->ec_chunk2[y]);
++ memcpy(wc->tspans[x]->ec_chunk2[y],wc->tspans[x]->ec_chunk1[y],
++ DAHDI_CHUNKSIZE);
++ memcpy(wc->tspans[x]->ec_chunk1[y],
++ wc->tspans[x]->span.chans[y]->writechunk,
++ DAHDI_CHUNKSIZE);
++ }
++ dahdi_receive(&wc->tspans[x]->span);
++ }
++ }
++}
++#endif
++
++#if (DAHDI_CHUNKSIZE != 8)
++#error Sorry, nextgen does not support chunksize != 8
++#endif
++
++static inline void __receive_span(struct t4_span *ts)
++{
++#ifdef VPM_SUPPORT
++ int y;
++ unsigned long merged;
++ merged = ts->dtmfactive & ts->dtmfmutemask;
++ if (merged) {
++ for (y=0;y<ts->span.channels;y++) {
++ /* Mute any DTMFs which are supposed to be muted */
++ if (test_bit(y, &merged)) {
++ memset(ts->span.chans[y]->readchunk, DAHDI_XLAW(0, ts->span.chans[y]), DAHDI_CHUNKSIZE);
++ }
++ }
++ }
++#endif
++
++#ifdef ENABLE_PREFETCH
++ prefetch((void *)(ts->readchunk));
++ prefetch((void *)(ts->writechunk));
++ prefetch((void *)(ts->readchunk + 8));
++ prefetch((void *)(ts->writechunk + 8));
++ prefetch((void *)(ts->readchunk + 16));
++ prefetch((void *)(ts->writechunk + 16));
++ prefetch((void *)(ts->readchunk + 24));
++ prefetch((void *)(ts->writechunk + 24));
++ prefetch((void *)(ts->readchunk + 32));
++ prefetch((void *)(ts->writechunk + 32));
++ prefetch((void *)(ts->readchunk + 40));
++ prefetch((void *)(ts->writechunk + 40));
++ prefetch((void *)(ts->readchunk + 48));
++ prefetch((void *)(ts->writechunk + 48));
++ prefetch((void *)(ts->readchunk + 56));
++ prefetch((void *)(ts->writechunk + 56));
++#endif
++
++ dahdi_ec_span(&ts->span);
++ dahdi_receive(&ts->span);
++}
++
++static inline void __transmit_span(struct t4_span *ts)
++{
++ dahdi_transmit(&ts->span);
++}
++
++#ifdef ENABLE_WORKQUEUES
++static void workq_handlespan(void *data)
++{
++ struct t4_span *ts = data;
++ struct t4 *wc = ts->owner;
++
++ __receive_span(ts);
++ __transmit_span(ts);
++ atomic_dec(&wc->worklist);
++ if (!atomic_read(&wc->worklist))
++ t4_pci_out(wc, WC_INTR, 0);
++}
++#else
++static void t4_prep_gen2(struct t4 *wc)
++{
++ int x;
++ for (x=0;x<wc->numspans;x++) {
++ if (wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) {
++ __receive_span(wc->tspans[x]);
++ __transmit_span(wc->tspans[x]);
++ }
++ }
++}
++
++#endif
++#ifdef SUPPORT_GEN1
++static void t4_transmitprep(struct t4 *wc, int irq)
++{
++ volatile unsigned int *writechunk;
++ int x,y,z;
++ unsigned int tmp;
++ int offset=0;
++ if (!wc->t1e1)
++ offset = 4;
++ if (irq & 1) {
++ /* First part */
++ writechunk = wc->writechunk + 1;
++ } else {
++ writechunk = wc->writechunk + DAHDI_CHUNKSIZE * 32 + 1;
++ }
++ for (y=0;y<wc->numspans;y++) {
++ if (wc->tspans[y]->span.flags & DAHDI_FLAG_RUNNING)
++ dahdi_transmit(&wc->tspans[y]->span);
++ }
++
++ for (x=0;x<DAHDI_CHUNKSIZE;x++) {
++ /* Once per chunk */
++ for (z=0;z<24;z++) {
++ /* All T1/E1 channels */
++ tmp = (wc->tspans[0]->span.chans[z]->writechunk[x] << 24);
++ writechunk[z+offset] = tmp;
++ }
++ if (wc->t1e1) {
++ for (z=24;z<31;z++) {
++ /* Only E1 channels now */
++ tmp = 0;
++ if (wc->tspans[0]->span.channels > 24)
++ tmp |= (wc->tspans[0]->span.chans[z]->writechunk[x] << 24);
++ writechunk[z] = tmp;
++ }
++ }
++ /* Advance pointer by 4 TDM frame lengths */
++ writechunk += 32;
++ }
++
++}
++#endif
++
++static void t4_check_sigbits(struct t4 *wc, int span)
++{
++ int a,i,rxs;
++ struct t4_span *ts = wc->tspans[span];
++
++ if (debug & DEBUG_RBS)
++ dev_notice(&wc->dev->dev, "Checking sigbits on span %d\n",
++ span + 1);
++
++ if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
++ return;
++ if (ts->spantype == TYPE_E1) {
++ for (i = 0; i < 15; i++) {
++ a = t4_framer_in(wc, span, 0x71 + i);
++ /* Get high channel in low bits */
++ rxs = (a & 0xf);
++ if (!(ts->span.chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
++ if (ts->span.chans[i+16]->rxsig != rxs)
++ dahdi_rbsbits(ts->span.chans[i+16], rxs);
++ }
++ rxs = (a >> 4) & 0xf;
++ if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
++ if (ts->span.chans[i]->rxsig != rxs)
++ dahdi_rbsbits(ts->span.chans[i], rxs);
++ }
++ }
++ } else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
++ for (i = 0; i < 24; i+=4) {
++ a = t4_framer_in(wc, span, 0x70 + (i>>2));
++ /* Get high channel in low bits */
++ rxs = (a & 0x3) << 2;
++ if (!(ts->span.chans[i+3]->sig & DAHDI_SIG_CLEAR)) {
++ if (ts->span.chans[i+3]->rxsig != rxs)
++ dahdi_rbsbits(ts->span.chans[i+3], rxs);
++ }
++ rxs = (a & 0xc);
++ if (!(ts->span.chans[i+2]->sig & DAHDI_SIG_CLEAR)) {
++ if (ts->span.chans[i+2]->rxsig != rxs)
++ dahdi_rbsbits(ts->span.chans[i+2], rxs);
++ }
++ rxs = (a >> 2) & 0xc;
++ if (!(ts->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
++ if (ts->span.chans[i+1]->rxsig != rxs)
++ dahdi_rbsbits(ts->span.chans[i+1], rxs);
++ }
++ rxs = (a >> 4) & 0xc;
++ if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
++ if (ts->span.chans[i]->rxsig != rxs)
++ dahdi_rbsbits(ts->span.chans[i], rxs);
++ }
++ }
++ } else {
++ for (i = 0; i < 24; i+=2) {
++ a = t4_framer_in(wc, span, 0x70 + (i>>1));
++ /* Get high channel in low bits */
++ rxs = (a & 0xf);
++ if (!(ts->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
++ /* XXX Not really reset on every trans! XXX */
++ if (ts->span.chans[i+1]->rxsig != rxs) {
++ dahdi_rbsbits(ts->span.chans[i+1], rxs);
++ }
++ }
++ rxs = (a >> 4) & 0xf;
++ if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
++ /* XXX Not really reset on every trans! XXX */
++ if (ts->span.chans[i]->rxsig != rxs) {
++ dahdi_rbsbits(ts->span.chans[i], rxs);
++ }
++ }
++ }
++ }
++}
++
++static void t4_check_alarms(struct t4 *wc, int span)
++{
++ unsigned char c, d, e;
++ int alarms;
++ int x,j;
++ struct t4_span *ts = wc->tspans[span];
++ unsigned long flags;
++
++ if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
++ return;
++
++ spin_lock_irqsave(&wc->reglock, flags);
++
++ c = __t4_framer_in(wc, span, 0x4c);
++ d = __t4_framer_in(wc, span, 0x4d);
++
++ /* Assume no alarms */
++ alarms = 0;
++
++ /* And consider only carrier alarms */
++ ts->span.alarms &= (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_NOTOPEN);
++
++ if (ts->spantype == TYPE_E1) {
++ if (c & 0x04) {
++ /* No multiframe found, force RAI high after 400ms only if
++ we haven't found a multiframe since last loss
++ of frame */
++ if (!(ts->spanflags & FLAG_NMF)) {
++ __t4_framer_out(wc, span, 0x20, 0x9f | 0x20); /* LIM0: Force RAI High */
++ ts->spanflags |= FLAG_NMF;
++ dev_notice(&wc->dev->dev,
++ "NMF workaround on!\n");
++ }
++ __t4_framer_out(wc, span, 0x1e, 0xc3); /* Reset to CRC4 mode */
++ __t4_framer_out(wc, span, 0x1c, 0xf2); /* Force Resync */
++ __t4_framer_out(wc, span, 0x1c, 0xf0); /* Force Resync */
++ } else if (!(c & 0x02)) {
++ if ((ts->spanflags & FLAG_NMF)) {
++ __t4_framer_out(wc, span, 0x20, 0x9f); /* LIM0: Clear forced RAI */
++ ts->spanflags &= ~FLAG_NMF;
++ dev_notice(&wc->dev->dev,
++ "NMF workaround off!\n");
++ }
++ }
++ } else {
++ /* Detect loopup code if we're not sending one */
++ if ((!ts->span.mainttimer) && (d & 0x08)) {
++ /* Loop-up code detected */
++ if ((ts->loopupcnt++ > 80) && (ts->span.maintstat != DAHDI_MAINT_REMOTELOOP)) {
++ __t4_framer_out(wc, span, 0x36, 0x08); /* LIM0: Disable any local loop */
++ __t4_framer_out(wc, span, 0x37, 0xf6 ); /* LIM1: Enable remote loop */
++ ts->span.maintstat = DAHDI_MAINT_REMOTELOOP;
++ }
++ } else
++ ts->loopupcnt = 0;
++ /* Same for loopdown code */
++ if ((!ts->span.mainttimer) && (d & 0x10)) {
++ /* Loop-down code detected */
++ if ((ts->loopdowncnt++ > 80) && (ts->span.maintstat == DAHDI_MAINT_REMOTELOOP)) {
++ __t4_framer_out(wc, span, 0x36, 0x08); /* LIM0: Disable any local loop */
++ __t4_framer_out(wc, span, 0x37, 0xf0 ); /* LIM1: Disable remote loop */
++ ts->span.maintstat = DAHDI_MAINT_NONE;
++ }
++ } else
++ ts->loopdowncnt = 0;
++ }
++
++ if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
++ for (x=0,j=0;x < ts->span.channels;x++)
++ if ((ts->span.chans[x]->flags & DAHDI_FLAG_OPEN)
++#ifdef CONFIG_DAHDI_NET
++ ||
++ (ts->span.chans[x]->flags & DAHDI_FLAG_NETDEV)
++#endif
++ )
++ j++;
++ if (!j)
++ alarms |= DAHDI_ALARM_NOTOPEN;
++ }
++
++ /* Loss of Frame Alignment */
++ if (c & 0x20) {
++ if (ts->alarmcount >= alarmdebounce) {
++
++ /* Disable Slip Interrupts */
++ e = __t4_framer_in(wc, span, 0x17);
++ __t4_framer_out(wc, span, 0x17, (e|0x03));
++
++ alarms |= DAHDI_ALARM_RED;
++ } else {
++ if (unlikely(debug && !ts->alarmcount)) {
++ /* starting to debounce LOF/LFA */
++ dev_info(&wc->dev->dev, "opvxd115: LOF/LFA "
++ "detected on span %d but debouncing "
++ "for %d ms\n", span + 1,
++ alarmdebounce);
++ }
++ ts->alarmcount++;
++ }
++ } else
++ ts->alarmcount = 0;
++
++ /* Loss of Signal */
++ if (c & 0x80) {
++ if (ts->losalarmcount >= losalarmdebounce) {
++ /* Disable Slip Interrupts */
++ e = __t4_framer_in(wc, span, 0x17);
++ __t4_framer_out(wc, span, 0x17, (e|0x03));
++
++ alarms |= DAHDI_ALARM_RED;
++ } else {
++ if (unlikely(debug && !ts->losalarmcount)) {
++ /* starting to debounce LOS */
++ dev_info(&wc->dev->dev, "opvxd115: LOS "
++ "detected on span %d but debouncing "
++ "for %d ms\n",
++ span + 1, losalarmdebounce);
++ }
++ ts->losalarmcount++;
++ }
++ } else
++ ts->losalarmcount = 0;
++
++ /* Alarm Indication Signal */
++ if (c & 0x40) {
++ if (ts->aisalarmcount >= aisalarmdebounce)
++ alarms |= DAHDI_ALARM_BLUE;
++ else {
++ if (unlikely(debug && !ts->aisalarmcount)) {
++ /* starting to debounce AIS */
++ dev_info(&wc->dev->dev, "opvxd115: AIS "
++ "detected on span %d but debouncing "
++ "for %d ms\n",
++ span + 1, aisalarmdebounce);
++ }
++ ts->aisalarmcount++;
++ }
++ } else
++ ts->aisalarmcount = 0;
++
++#ifdef DAHDI_SPAN_OPS
++ /* Add detailed alarm status information to a red alarm state */
++ if (alarms & DAHDI_ALARM_RED) {
++ if (c & FRS0_LOS)
++ alarms |= DAHDI_ALARM_LOS;
++ if (c & FRS0_LFA)
++ alarms |= DAHDI_ALARM_LFA;
++ if (c & FRS0_LMFA)
++ alarms |= DAHDI_ALARM_LMFA;
++ }
++
++ if (unlikely(debug)) {
++ /* Check to ensure the xmit line isn't shorted */
++ if (unlikely(d & FRS1_XLS)) {
++ dev_info(&wc->dev->dev,
++ "Detected a possible hardware malfunction"\
++ " this card may need servicing\n");
++ }
++ }
++#endif
++
++ if (((!ts->span.alarms) && alarms) ||
++ (ts->span.alarms && (!alarms)))
++ set_bit(T4_CHECK_TIMING, &wc->checkflag);
++
++ /* Keep track of recovering */
++ if ((!alarms) && ts->span.alarms)
++ ts->alarmtimer = DAHDI_ALARMSETTLE_TIME;
++ if (ts->alarmtimer)
++ alarms |= DAHDI_ALARM_RECOVER;
++
++ /* If receiving alarms, go into Yellow alarm state */
++ if (alarms && !(ts->spanflags & FLAG_SENDINGYELLOW)) {
++ /* We manually do yellow alarm to handle RECOVER and NOTOPEN, otherwise it's auto anyway */
++ unsigned char fmr4;
++ fmr4 = __t4_framer_in(wc, span, 0x20);
++ __t4_framer_out(wc, span, 0x20, fmr4 | 0x20);
++ dev_info(&wc->dev->dev, "Setting yellow alarm span %d\n",
++ span+1);
++ ts->spanflags |= FLAG_SENDINGYELLOW;
++ } else if ((!alarms) && (ts->spanflags & FLAG_SENDINGYELLOW)) {
++ unsigned char fmr4;
++ /* We manually do yellow alarm to handle RECOVER */
++ fmr4 = __t4_framer_in(wc, span, 0x20);
++ __t4_framer_out(wc, span, 0x20, fmr4 & ~0x20);
++ dev_info(&wc->dev->dev, "Clearing yellow alarm span %d\n",
++ span+1);
++
++ /* Re-enable timing slip interrupts */
++ e = __t4_framer_in(wc, span, 0x17);
++
++ __t4_framer_out(wc, span, 0x17, (e & ~(0x03)));
++
++ ts->spanflags &= ~FLAG_SENDINGYELLOW;
++ }
++
++ /* Re-check the timing source when we enter/leave alarm, not withstanding
++ yellow alarm */
++ if (c & 0x10) { /* receiving yellow (RAI) */
++ if (ts->yelalarmcount >= yelalarmdebounce)
++ alarms |= DAHDI_ALARM_YELLOW;
++ else {
++ if (unlikely(debug && !ts->yelalarmcount)) {
++ /* starting to debounce AIS */
++ dev_info(&wc->dev->dev, "wct%dxxp: yellow "
++ "(RAI) detected on span %d but "
++ "debouncing for %d ms\n",
++ wc->numspans, span + 1,
++ yelalarmdebounce);
++ }
++ ts->yelalarmcount++;
++ }
++ } else
++ ts->yelalarmcount = 0;
++
++ if (ts->span.mainttimer || ts->span.maintstat)
++ alarms |= DAHDI_ALARM_LOOPBACK;
++ ts->span.alarms = alarms;
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ dahdi_alarm_notify(&ts->span);
++}
++
++static void t4_do_counters(struct t4 *wc)
++{
++ int span;
++ for (span=0;span<wc->numspans;span++) {
++ struct t4_span *ts = wc->tspans[span];
++ int docheck=0;
++
++ spin_lock(&wc->reglock);
++ if (ts->loopupcnt || ts->loopdowncnt || ts->alarmcount
++ || ts->losalarmcount || ts->aisalarmcount
++ || ts->yelalarmcount)
++ docheck++;
++
++ if (ts->alarmtimer) {
++ if (!--ts->alarmtimer) {
++ docheck++;
++ ts->span.alarms &= ~(DAHDI_ALARM_RECOVER);
++ }
++ }
++ spin_unlock(&wc->reglock);
++ if (docheck) {
++ t4_check_alarms(wc, span);
++ dahdi_alarm_notify(&ts->span);
++ }
++ }
++}
++
++static inline void __handle_leds(struct t4 *wc)
++{
++ int x;
++
++ wc->blinktimer++;
++ for (x=0;x<wc->numspans;x++) {
++ struct t4_span *ts = wc->tspans[x];
++ if (ts->span.flags & DAHDI_FLAG_RUNNING) {
++ if ((ts->span.alarms & (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE)) || ts->losalarmcount) {
++#ifdef FANCY_ALARM
++ if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
++ __t4_set_led(wc, x, WC_RED);
++ }
++ if (wc->blinktimer == 0xf) {
++ __t4_set_led(wc, x, WC_OFF);
++ }
++#else
++ if (wc->blinktimer == 160) {
++ __t4_set_led(wc, x, WC_RED);
++ } else if (wc->blinktimer == 480) {
++ __t4_set_led(wc, x, WC_OFF);
++ }
++#endif
++ } else if (ts->span.alarms & DAHDI_ALARM_YELLOW) {
++ /* Yellow Alarm */
++ __t4_set_led(wc, x, WC_YELLOW);
++ } else if (ts->span.mainttimer || ts->span.maintstat) {
++#ifdef FANCY_ALARM
++ if (wc->blinktimer == (altab[wc->alarmpos] >> 1)) {
++ __t4_set_led(wc, x, WC_GREEN);
++ }
++ if (wc->blinktimer == 0xf) {
++ __t4_set_led(wc, x, WC_OFF);
++ }
++#else
++ if (wc->blinktimer == 160) {
++ __t4_set_led(wc, x, WC_GREEN);
++ } else if (wc->blinktimer == 480) {
++ __t4_set_led(wc, x, WC_OFF);
++ }
++#endif
++ } else {
++ /* No Alarm */
++ __t4_set_led(wc, x, WC_GREEN);
++ }
++ } else
++ __t4_set_led(wc, x, WC_OFF);
++
++ }
++#ifdef FANCY_ALARM
++ if (wc->blinktimer == 0xf) {
++ wc->blinktimer = -1;
++ wc->alarmpos++;
++ if (wc->alarmpos >= (sizeof(altab) / sizeof(altab[0])))
++ wc->alarmpos = 0;
++ }
++#else
++ if (wc->blinktimer == 480)
++ wc->blinktimer = 0;
++#endif
++}
++
++static inline void t4_framer_interrupt(struct t4 *wc, int span)
++{
++ unsigned char gis, isr0, isr1, isr2, isr3, isr4;
++#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
++ /* Check interrupts for a given span */
++ unsigned char reg;
++#endif
++ int readsize = -1;
++ struct t4_span *ts = wc->tspans[span];
++ struct dahdi_chan *sigchan;
++ unsigned long flags;
++
++
++ /* 1st gen cards isn't used interrupts */
++ gis = t4_framer_in(wc, span, FRMR_GIS);
++ isr0 = (gis & FRMR_GIS_ISR0) ? t4_framer_in(wc, span, FRMR_ISR0) : 0;
++ isr1 = (gis & FRMR_GIS_ISR1) ? t4_framer_in(wc, span, FRMR_ISR1) : 0;
++ isr2 = (gis & FRMR_GIS_ISR2) ? t4_framer_in(wc, span, FRMR_ISR2) : 0;
++ isr3 = (gis & FRMR_GIS_ISR3) ? t4_framer_in(wc, span, FRMR_ISR3) : 0;
++ isr4 = (gis & FRMR_GIS_ISR4) ? t4_framer_in(wc, span, FRMR_ISR4) : 0;
++
++ if ((debug & DEBUG_FRAMER) && !(isr3 & ISR3_SEC)) {
++ dev_info(&wc->dev->dev, "gis: %02x, isr0: %02x, isr1: %02x, "\
++ "isr2: %02x, isr3: %08x, isr4: %02x, intcount=%u\n",
++ gis, isr0, isr1, isr2, isr3, isr4, wc->intcount);
++ }
++
++#if (defined(DAHDI_SPAN_OPS) || defined(DAHDI_SPAN_MODULE) )
++ /* Collect performance counters once per second */
++ if (isr3 & ISR3_SEC) {
++ ts->span.count.fe += t4_framer_in(wc, span, FECL_T);
++ ts->span.count.crc4 += t4_framer_in(wc, span, CEC1L_T);
++ ts->span.count.cv += t4_framer_in(wc, span, CVCL_T);
++ ts->span.count.ebit += t4_framer_in(wc, span, EBCL_T);
++ ts->span.count.be += t4_framer_in(wc, span, BECL_T);
++ ts->span.count.prbs = t4_framer_in(wc, span, FRS1_T);
++ }
++
++ /* Collect errored second counter once per second */
++ if (isr3 & ISR3_ES) {
++ ts->span.count.errsec += 1;
++ }
++
++ if (isr3 & 0x08) {
++ reg = t4_framer_in(wc, span, FRS1_T);
++ dev_info(&wc->dev->dev, "FRS1: %d\n", reg);
++ if (reg & LLBDD) {
++ dev_info(&wc->dev->dev, "Line loop-back activation "\
++ "signal detected with status: %01d "\
++ "for span %d\n", reg & LLBAD, span+1);
++ }
++ }
++#endif
++
++ if (isr0)
++ t4_check_sigbits(wc, span);
++
++ if (ts->spantype == TYPE_E1) {
++ /* E1 checks */
++ if ((isr3 & 0x38) || isr2 || isr1)
++ t4_check_alarms(wc, span);
++ } else {
++ /* T1 checks */
++ if (isr2 || (isr3 & 0x08))
++ t4_check_alarms(wc, span);
++ }
++ if (!ts->span.alarms) {
++ if ((isr3 & 0x3) || (isr4 & 0xc0))
++ ts->span.count.timingslips++;
++
++ if (debug & DEBUG_MAIN) {
++ if (isr3 & 0x02)
++ dev_notice(&wc->dev->dev, "opvxd115: RECEIVE "
++ "slip NEGATIVE on span %d\n",
++ span + 1);
++ if (isr3 & 0x01)
++ dev_notice(&wc->dev->dev, "opvxd115: RECEIVE "
++ "slip POSITIVE on span %d\n",
++ span + 1);
++ if (isr4 & 0x80)
++ dev_notice(&wc->dev->dev, "opvxd115: TRANSMIT "
++ "slip POSITIVE on span %d\n",
++ span + 1);
++ if (isr4 & 0x40)
++ dev_notice(&wc->dev->dev, "opvxd115: TRANSMIT "
++ "slip NEGATIVE on span %d\n",
++ span + 1);
++ }
++ } else
++ ts->span.count.timingslips = 0;
++
++ spin_lock_irqsave(&wc->reglock, flags);
++ /* HDLC controller checks - receive side */
++ if (!ts->sigchan) {
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ return;
++ }
++
++ sigchan = ts->sigchan;
++ spin_unlock_irqrestore(&wc->reglock, flags);
++
++ if (isr0 & FRMR_ISR0_RME) {
++ readsize = (t4_framer_in(wc, span, FRMR_RBCH) << 8) | t4_framer_in(wc, span, FRMR_RBCL);
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "Received data length is %d "
++ "(%d)\n", readsize,
++ readsize & FRMR_RBCL_MAX_SIZE);
++ /* RPF isn't set on last part of frame */
++ if ((readsize > 0) && ((readsize &= FRMR_RBCL_MAX_SIZE) == 0))
++ readsize = FRMR_RBCL_MAX_SIZE + 1;
++ } else if (isr0 & FRMR_ISR0_RPF)
++ readsize = FRMR_RBCL_MAX_SIZE + 1;
++
++ if (readsize > 0) {
++ int i;
++ unsigned char readbuf[FRMR_RBCL_MAX_SIZE + 1];
++
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "Framer %d: Got RPF/RME! "
++ "readsize is %d\n", sigchan->span->offset,
++ readsize);
++
++ for (i = 0; i < readsize; i++)
++ readbuf[i] = t4_framer_in(wc, span, FRMR_RXFIFO);
++
++ /* Tell the framer to clear the RFIFO */
++ t4_framer_cmd_wait(wc, span, FRMR_CMDR_RMC);
++
++ if (debug & DEBUG_FRAMER) {
++ dev_notice(&wc->dev->dev, "RX(");
++ for (i = 0; i < readsize; i++)
++ dev_notice(&wc->dev->dev, "%s%02x",
++ (i ? " " : ""), readbuf[i]);
++ dev_notice(&wc->dev->dev, ")\n");
++ }
++
++ if (isr0 & FRMR_ISR0_RME) {
++ /* Do checks for HDLC problems */
++ unsigned char rsis = readbuf[readsize-1];
++#if 0
++ unsigned int olddebug = debug;
++#endif
++ unsigned char rsis_reg = t4_framer_in(wc, span, FRMR_RSIS);
++
++#if 0
++ if ((rsis != 0xA2) || (rsis != rsis_reg))
++ debug |= DEBUG_FRAMER;
++#endif
++
++ ++ts->frames_in;
++ if ((debug & DEBUG_FRAMER) && !(ts->frames_in & 0x0f))
++ dev_notice(&wc->dev->dev, "Received %d frames "
++ "on span %d\n", ts->frames_in, span);
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "Received HDLC frame"
++ " %d. RSIS = 0x%x (%x)\n",
++ ts->frames_in, rsis, rsis_reg);
++ if (!(rsis & FRMR_RSIS_CRC16)) {
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "CRC check "
++ "failed %d\n", span);
++ dahdi_hdlc_abort(sigchan, DAHDI_EVENT_BADFCS);
++ } else if (rsis & FRMR_RSIS_RAB) {
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "ABORT of "
++ "current frame due to "
++ "overflow %d\n", span);
++ dahdi_hdlc_abort(sigchan, DAHDI_EVENT_ABORT);
++ } else if (rsis & FRMR_RSIS_RDO) {
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "HDLC "
++ "overflow occured %d\n",
++ span);
++ dahdi_hdlc_abort(sigchan, DAHDI_EVENT_OVERRUN);
++ } else if (!(rsis & FRMR_RSIS_VFR)) {
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "Valid Frame"
++ " check failed on span %d\n",
++ span);
++ dahdi_hdlc_abort(sigchan, DAHDI_EVENT_ABORT);
++ } else {
++ dahdi_hdlc_putbuf(sigchan, readbuf, readsize - 1);
++ dahdi_hdlc_finish(sigchan);
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "Received "
++ "valid HDLC frame on span %d"
++ "\n", span);
++ }
++#if 0
++ debug = olddebug;
++#endif
++ } else if (isr0 & FRMR_ISR0_RPF)
++ dahdi_hdlc_putbuf(sigchan, readbuf, readsize);
++ }
++
++ /* Transmit side */
++ if (isr1 & FRMR_ISR1_XDU) {
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "XDU: Resetting signal "
++ "controller!\n");
++ t4_framer_cmd_wait(wc, span, FRMR_CMDR_SRES);
++ } else if (isr1 & FRMR_ISR1_XPR) {
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "Sigchan %d is %p\n",
++ sigchan->chanpos, sigchan);
++
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "Framer %d: Got XPR!\n",
++ sigchan->span->offset);
++ t4_hdlc_xmit_fifo(wc, span, ts);
++ }
++
++ if (isr1 & FRMR_ISR1_ALLS) {
++ if (debug & DEBUG_FRAMER)
++ dev_notice(&wc->dev->dev, "ALLS received\n");
++ }
++}
++
++#ifdef SUPPORT_GEN1
++static irqreturn_t t4_interrupt(int irq, void *dev_id)
++{
++ struct t4 *wc = dev_id;
++ unsigned long flags;
++ int x;
++
++ unsigned int status;
++ unsigned int status2;
++
++#if 0
++ if (wc->intcount < 20)
++ dev_notice(&wc->dev->dev, "Pre-interrupt\n");
++#endif
++
++ /* Make sure it's really for us */
++ status = __t4_pci_in(wc, WC_INTR);
++
++ /* Process framer interrupts */
++ status2 = t4_framer_in(wc, 0, FRMR_CIS);
++ if (status2 & 0x0f) {
++ for (x = 0; x < wc->numspans; ++x) {
++ if (status2 & (1 << x))
++ t4_framer_interrupt(wc, x);
++ }
++ }
++
++ /* Ignore if it's not for us */
++ if (!status)
++ return IRQ_NONE;
++
++ __t4_pci_out(wc, WC_INTR, 0);
++
++ if (!wc->spansstarted) {
++ dev_notice(&wc->dev->dev, "Not prepped yet!\n");
++ return IRQ_NONE;
++ }
++
++ wc->intcount++;
++#if 0
++ if (wc->intcount < 20)
++ dev_notice(&wc->dev->dev, "Got interrupt, status = %08x\n",
++ status);
++#endif
++
++ if (status & 0x3) {
++ t4_receiveprep(wc, status);
++ t4_transmitprep(wc, status);
++ }
++
++#if 0
++ if ((wc->intcount < 10) || !(wc->intcount % 1000)) {
++ status2 = t4_framer_in(wc, 0, FRMR_CIS);
++ dev_notice(&wc->dev->dev, "Status2: %04x\n", status2);
++ for (x = 0;x<wc->numspans;x++) {
++ status2 = t4_framer_in(wc, x, FRMR_FRS0);
++ dev_notice(&wc->dev->dev, "FRS0/%d: %04x\n", x,
++ status2);
++ }
++ }
++#endif
++ t4_do_counters(wc);
++
++ x = wc->intcount & 15 /* 63 */;
++ switch(x) {
++ case 0:
++ case 1:
++ case 2:
++ case 3:
++ t4_check_sigbits(wc, x);
++ break;
++ case 4:
++ case 5:
++ case 6:
++ case 7:
++ t4_check_alarms(wc, x - 4);
++ break;
++ }
++
++ spin_lock_irqsave(&wc->reglock, flags);
++
++ __handle_leds(wc);
++
++ if (test_bit(T4_CHECK_TIMING, &wc->checkflag))
++ __t4_set_timing_source_auto(wc);
++
++ spin_unlock_irqrestore(&wc->reglock, flags);
++
++ return IRQ_RETVAL(1);
++}
++#endif
++
++static int t4_allocate_buffers(struct t4 *wc, int numbufs, volatile unsigned int **oldalloc, dma_addr_t *oldwritedma)
++{
++ volatile unsigned int *alloc;
++ dma_addr_t writedma;
++
++ alloc =
++ /* 32 channels, Double-buffer, Read/Write, 4 spans */
++ (unsigned int *)pci_alloc_consistent(wc->dev, numbufs * T4_BASE_SIZE * 2, &writedma);
++
++ if (!alloc) {
++ dev_notice(&wc->dev->dev, "wct%dxxp: Unable to allocate "
++ "DMA-able memory\n", wc->numspans);
++ return -ENOMEM;
++ }
++
++ if (oldwritedma)
++ *oldwritedma = wc->writedma;
++ if (oldalloc)
++ *oldalloc = wc->writechunk;
++
++ wc->writechunk = alloc;
++ wc->writedma = writedma;
++
++ /* Read is after the whole write piece (in words) */
++ wc->readchunk = wc->writechunk + (T4_BASE_SIZE * numbufs) / 4;
++
++ /* Same thing but in bytes... */
++ wc->readdma = wc->writedma + (T4_BASE_SIZE * numbufs);
++
++ wc->numbufs = numbufs;
++
++ /* Initialize Write/Buffers to all blank data */
++ memset((void *)wc->writechunk,0x00, T4_BASE_SIZE * numbufs);
++ memset((void *)wc->readchunk,0xff, T4_BASE_SIZE * numbufs);
++
++ dev_notice(&wc->dev->dev, "DMA memory base of size %d at %p. Read: "
++ "%p and Write %p\n", numbufs * T4_BASE_SIZE * 2,
++ wc->writechunk, wc->readchunk, wc->writechunk);
++
++ return 0;
++}
++
++static void t4_increase_latency(struct t4 *wc, int newlatency)
++{
++ unsigned long flags;
++ volatile unsigned int *oldalloc;
++ dma_addr_t oldaddr;
++ int oldbufs;
++
++ spin_lock_irqsave(&wc->reglock, flags);
++
++ __t4_pci_out(wc, WC_DMACTRL, 0x00000000);
++ /* Acknowledge any pending interrupts */
++ __t4_pci_out(wc, WC_INTR, 0x00000000);
++
++ __t4_pci_in(wc, WC_VERSION);
++
++ oldbufs = wc->numbufs;
++
++ if (t4_allocate_buffers(wc, newlatency, &oldalloc, &oldaddr)) {
++ dev_info(&wc->dev->dev, "Error allocating latency buffers for "
++ "latency of %d\n", newlatency);
++ __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ return;
++ }
++
++ __t4_pci_out(wc, WC_RDADDR, wc->readdma);
++ __t4_pci_out(wc, WC_WRADDR, wc->writedma);
++
++ __t4_pci_in(wc, WC_VERSION);
++
++ __t4_pci_out(wc, 5, (ms_per_irq << 16) | newlatency);
++ __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++
++ __t4_pci_in(wc, WC_VERSION);
++
++ wc->rxident = 0;
++ wc->lastindex = 0;
++
++ spin_unlock_irqrestore(&wc->reglock, flags);
++
++ pci_free_consistent(wc->dev, T4_BASE_SIZE * oldbufs * 2, (void *)oldalloc, oldaddr);
++
++ dev_info(&wc->dev->dev, "Increased latency to %d\n", newlatency);
++
++}
++
++static void t4_isr_bh(unsigned long data)
++{
++ struct t4 *wc = (struct t4 *)data;
++
++ if (test_bit(T4_CHANGE_LATENCY, &wc->checkflag)) {
++ if (wc->needed_latency != wc->numbufs) {
++ t4_increase_latency(wc, wc->needed_latency);
++ clear_bit(T4_CHANGE_LATENCY, &wc->checkflag);
++ }
++ }
++#ifdef VPM_SUPPORT
++ if (wc->vpm) {
++ if (test_and_clear_bit(T4_CHECK_VPM, &wc->checkflag)) {
++ if (wc->vpm450m) {
++ /* How stupid is it that the octasic can't generate an
++ interrupt when there's a tone, in spite of what their
++ documentation says? */
++ t4_check_vpm450(wc);
++ } else
++ t4_check_vpm400(wc, wc->vpm400checkstatus);
++ }
++ }
++#endif
++}
++
++static irqreturn_t t4_interrupt_gen2(int irq, void *dev_id)
++{
++ struct t4 *wc = dev_id;
++ unsigned int status;
++ unsigned char rxident, expected;
++
++ /* Check this first in case we get a spurious interrupt */
++ if (unlikely(test_bit(T4_STOP_DMA, &wc->checkflag))) {
++ /* Stop DMA cleanly if requested */
++ wc->dmactrl = 0x0;
++ t4_pci_out(wc, WC_DMACTRL, 0x00000000);
++ /* Acknowledge any pending interrupts */
++ t4_pci_out(wc, WC_INTR, 0x00000000);
++ spin_lock(&wc->reglock);
++ __t4_set_sclk_src(wc, WC_SELF, 0, 0);
++ spin_unlock(&wc->reglock);
++ return IRQ_RETVAL(1);
++ }
++
++ /* Make sure it's really for us */
++ status = __t4_pci_in(wc, WC_INTR);
++
++ /* Ignore if it's not for us */
++ if (!(status & 0x7)) {
++ return IRQ_NONE;
++ }
++
++#ifdef ENABLE_WORKQUEUES
++ __t4_pci_out(wc, WC_INTR, status & 0x00000008);
++#endif
++
++ if (unlikely(!wc->spansstarted)) {
++ dev_info(&wc->dev->dev, "Not prepped yet!\n");
++ return IRQ_NONE;
++ }
++
++ wc->intcount++;
++
++ if ((wc->flags & FLAG_5THGEN) && (status & 0x2)) {
++ rxident = (status >> 16) & 0x7f;
++ expected = (wc->rxident + ms_per_irq) % 128;
++
++ if ((rxident != expected) && !test_bit(T4_IGNORE_LATENCY, &wc->checkflag)) {
++ int needed_latency;
++ int smallest_max;
++
++ if (debug & DEBUG_MAIN)
++ dev_warn(&wc->dev->dev, "Missed interrupt. "
++ "Expected ident of %d and got ident "
++ "of %d\n", expected, rxident);
++
++ if (test_bit(T4_IGNORE_LATENCY, &wc->checkflag)) {
++ dev_info(&wc->dev->dev,
++ "Should have ignored latency\n");
++ }
++ if (rxident > wc->rxident) {
++ needed_latency = rxident - wc->rxident;
++ } else {
++ needed_latency = (128 - wc->rxident) + rxident;
++ }
++
++ needed_latency += 1;
++
++ smallest_max = (max_latency >= GEN5_MAX_LATENCY) ? GEN5_MAX_LATENCY : max_latency;
++
++ if (needed_latency > smallest_max) {
++ dev_info(&wc->dev->dev, "Truncating latency "
++ "request to %d instead of %d\n",
++ smallest_max, needed_latency);
++ needed_latency = smallest_max;
++ }
++
++ if (needed_latency > wc->numbufs) {
++ int x;
++
++ dev_info(&wc->dev->dev, "Need to increase "
++ "latency. Estimated latency should "
++ "be %d\n", needed_latency);
++ for (x = 0; x < wc->numspans; x++)
++ wc->ddev->irqmisses++;
++ wc->needed_latency = needed_latency;
++ __t4_pci_out(wc, WC_DMACTRL, 0x00000000);
++ set_bit(T4_CHANGE_LATENCY, &wc->checkflag);
++ goto out;
++ }
++ }
++
++ wc->rxident = rxident;
++ }
++
++ if (unlikely((wc->intcount < 20)))
++
++ dev_info(&wc->dev->dev, "2G: Got interrupt, status = %08x, "
++ "CIS = %04x\n", status, t4_framer_in(wc, 0, FRMR_CIS));
++
++ if (likely(status & 0x2)) {
++#ifdef ENABLE_WORKQUEUES
++ int cpus = num_online_cpus();
++ atomic_set(&wc->worklist, wc->numspans);
++ if (wc->tspans[0]->span.flags & DAHDI_FLAG_RUNNING)
++ t4_queue_work(wc->workq, &wc->tspans[0]->swork, 0);
++ else
++ atomic_dec(&wc->worklist);
++#else
++#if 1
++ unsigned int reg5 = __t4_pci_in(wc, 5);
++ if (wc->intcount < 20) {
++
++ dev_info(&wc->dev->dev, "Reg 5 is %08x\n", reg5);
++ }
++#endif
++
++ if (wc->flags & FLAG_5THGEN) {
++ unsigned int current_index = (reg5 >> 8) & 0x7f;
++
++ while (((wc->lastindex + 1) % wc->numbufs) != current_index) {
++ wc->lastindex = (wc->lastindex + 1) % wc->numbufs;
++ setup_chunks(wc, wc->lastindex);
++ t4_prep_gen2(wc);
++ }
++ } else {
++ t4_prep_gen2(wc);
++ }
++
++#endif
++ t4_do_counters(wc);
++ spin_lock(&wc->reglock);
++ __handle_leds(wc);
++ spin_unlock(&wc->reglock);
++
++ }
++
++ if (unlikely(status & 0x1)) {
++ unsigned char cis;
++
++ cis = t4_framer_in(wc, 0, FRMR_CIS);
++ if (cis & FRMR_CIS_GIS1)
++ t4_framer_interrupt(wc, 0);
++ if (cis & FRMR_CIS_GIS2)
++ t4_framer_interrupt(wc, 1);
++ if (cis & FRMR_CIS_GIS3)
++ t4_framer_interrupt(wc, 2);
++ if (cis & FRMR_CIS_GIS4)
++ t4_framer_interrupt(wc, 3);
++ }
++
++ if (wc->vpm && vpmdtmfsupport) {
++ if (wc->vpm450m) {
++ /* How stupid is it that the octasic can't generate an
++ interrupt when there's a tone, in spite of what their
++ documentation says? */
++ if (!(wc->intcount & 0xf)) {
++ set_bit(T4_CHECK_VPM, &wc->checkflag);
++ }
++ } else if ((status & 0xff00) != 0xff00) {
++ wc->vpm400checkstatus = (status & 0xff00) >> 8;
++ set_bit(T4_CHECK_VPM, &wc->checkflag);
++ }
++ }
++
++ spin_lock(&wc->reglock);
++
++ if (unlikely(test_bit(T4_CHECK_TIMING, &wc->checkflag))) {
++ __t4_set_timing_source_auto(wc);
++ }
++
++ spin_unlock(&wc->reglock);
++
++out:
++ if (unlikely(test_bit(T4_CHANGE_LATENCY, &wc->checkflag) || test_bit(T4_CHECK_VPM, &wc->checkflag)))
++ tasklet_schedule(&wc->t4_tlet);
++
++#ifndef ENABLE_WORKQUEUES
++ __t4_pci_out(wc, WC_INTR, 0);
++#endif
++
++ return IRQ_RETVAL(1);
++}
++
++#ifdef SUPPORT_GEN1
++static int t4_reset_dma(struct t4 *wc)
++{
++ /* Turn off DMA and such */
++ wc->dmactrl = 0x0;
++ t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++ t4_pci_out(wc, WC_COUNT, 0);
++ t4_pci_out(wc, WC_RDADDR, 0);
++ t4_pci_out(wc, WC_WRADDR, 0);
++ t4_pci_out(wc, WC_INTR, 0);
++ /* Turn it all back on */
++ t4_pci_out(wc, WC_RDADDR, wc->readdma);
++ t4_pci_out(wc, WC_WRADDR, wc->writedma);
++ t4_pci_out(wc, WC_COUNT, ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 18) | ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 2));
++ t4_pci_out(wc, WC_INTR, 0);
++#ifdef VPM_SUPPORT
++ wc->dmactrl = 0xc0000000 | (1 << 29) | wc->vpm;
++#else
++ wc->dmactrl = 0xc0000000 | (1 << 29);
++#endif
++ if (noburst)
++ wc->dmactrl |= (1 << 26);
++ t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++ return 0;
++}
++#endif
++
++#ifdef VPM_SUPPORT
++static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold)
++{
++ unsigned int x;
++
++ for (x = 0; x < 8; x++) {
++ t4_vpm_out(wc, x, 0xC4, (threshold >> 8) & 0xFF);
++ t4_vpm_out(wc, x, 0xC5, (threshold & 0xFF));
++ }
++ dev_info(&wc->dev->dev, "VPM: DTMF threshold set to %d\n", threshold);
++}
++
++static unsigned int t4_vpm_mask(int chip)
++{
++ unsigned int mask=0;
++ switch(vpmspans) {
++ case 4:
++ mask = 0x55555555 << (chip >> 2);
++ break;
++ case 2:
++ mask = 0x11111111 << (chip >> 1);
++ break;
++ case 1:
++ mask = 0x01010101 << chip;
++ break;
++ }
++ return mask;
++}
++
++static int t4_vpm_spanno(int chip)
++{
++ int spanno = 0;
++ switch(vpmspans) {
++ case 4:
++ spanno = chip & 0x3;
++ break;
++ case 2:
++ spanno = chip & 0x1;
++ break;
++ /* Case 1 is implicit */
++ }
++ return spanno;
++}
++
++static int t4_vpm_echotail(void)
++{
++ int echotail = 0x01ff;
++ switch(vpmspans) {
++ case 4:
++ echotail = 0x007f;
++ break;
++ case 2:
++ echotail = 0x00ff;
++ break;
++ /* Case 1 is implicit */
++ }
++ return echotail;
++}
++
++static void t4_vpm450_init(struct t4 *wc)
++{
++ unsigned int check1, check2;
++ int laws[1] = { 0, };
++ int x;
++ unsigned int vpm_capacity;
++ struct firmware embedded_firmware;
++ const struct firmware *firmware = &embedded_firmware;
++#if !defined(HOTPLUG_FIRMWARE)
++ extern void _binary_dahdi_fw_oct6114_032_bin_size;
++ extern void _binary_dahdi_fw_oct6114_064_bin_size;
++ extern void _binary_dahdi_fw_oct6114_128_bin_size;
++ extern u8 _binary_dahdi_fw_oct6114_032_bin_start[];
++ extern u8 _binary_dahdi_fw_oct6114_064_bin_start[];
++ extern u8 _binary_dahdi_fw_oct6114_128_bin_start[];
++#else
++ static const char oct032_firmware[] = "dahdi-fw-oct6114-032.bin";
++ static const char oct064_firmware[] = "dahdi-fw-oct6114-064.bin";
++ static const char oct128_firmware[] = "dahdi-fw-oct6114-128.bin";
++#endif
++
++ if (!vpmsupport) {
++ dev_info(&wc->dev->dev, "VPM450: Support Disabled\n");
++ return;
++ }
++
++ /* Turn on GPIO/DATA mux if supported */
++ t4_gpio_setdir(wc, (1 << 24), (1 << 24));
++ __t4_raw_oct_out(wc, 0x000a, 0x5678);
++ __t4_raw_oct_out(wc, 0x0004, 0x1234);
++ check1 = __t4_raw_oct_in(wc, 0x0004);
++ check2 = __t4_raw_oct_in(wc, 0x000a);
++ if (debug)
++ dev_notice(&wc->dev->dev, "OCT Result: %04x/%04x\n",
++ __t4_raw_oct_in(wc, 0x0004),
++ __t4_raw_oct_in(wc, 0x000a));
++ if (__t4_raw_oct_in(wc, 0x0004) != 0x1234) {
++ dev_notice(&wc->dev->dev, "VPM450: Not Present\n");
++ return;
++ }
++
++ /* Setup alaw vs ulaw rules */
++ for (x = 0;x < wc->numspans; x++) {
++ if (wc->tspans[x]->span.channels > 24)
++ laws[x] = 1;
++ }
++
++ switch ((vpm_capacity = get_vpm450m_capacity(wc))) {
++ case 32:
++#if defined(HOTPLUG_FIRMWARE)
++ if ((request_firmware(&firmware, oct032_firmware, &wc->dev->dev) != 0) ||
++ !firmware) {
++ dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
++ "available from userspace\n", oct032_firmware);
++ return;
++ }
++#else
++ embedded_firmware.data = _binary_dahdi_fw_oct6114_032_bin_start;
++ /* Yes... this is weird. objcopy gives us a symbol containing
++ the size of the firmware, not a pointer a variable containing
++ the size. The only way we can get the value of the symbol
++ is to take its address, so we define it as a pointer and
++ then cast that value to the proper type.
++ */
++ embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_032_bin_size;
++#endif
++ break;
++ case 64:
++#if defined(HOTPLUG_FIRMWARE)
++ if ((request_firmware(&firmware, oct064_firmware, &wc->dev->dev) != 0) ||
++ !firmware) {
++ dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
++ "available from userspace\n", oct064_firmware);
++ return;
++ }
++#else
++ embedded_firmware.data = _binary_dahdi_fw_oct6114_064_bin_start;
++ /* Yes... this is weird. objcopy gives us a symbol containing
++ the size of the firmware, not a pointer a variable containing
++ the size. The only way we can get the value of the symbol
++ is to take its address, so we define it as a pointer and
++ then cast that value to the proper type.
++ */
++ embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_064_bin_size;
++#endif
++ break;
++ case 128:
++#if defined(HOTPLUG_FIRMWARE)
++ if ((request_firmware(&firmware, oct128_firmware, &wc->dev->dev) != 0) ||
++ !firmware) {
++ dev_notice(&wc->dev->dev, "VPM450: firmware %s not "
++ "available from userspace\n", oct128_firmware);
++ return;
++ }
++#else
++ embedded_firmware.data = _binary_dahdi_fw_oct6114_128_bin_start;
++ /* Yes... this is weird. objcopy gives us a symbol containing
++ the size of the firmware, not a pointer a variable containing
++ the size. The only way we can get the value of the symbol
++ is to take its address, so we define it as a pointer and
++ then cast that value to the proper type.
++ */
++ embedded_firmware.size = (size_t) &_binary_dahdi_fw_oct6114_128_bin_size;
++#endif
++ break;
++ default:
++ dev_notice(&wc->dev->dev, "Unsupported channel capacity found "
++ "on VPM module (%d).\n", vpm_capacity);
++ return;
++ }
++
++ if (!(wc->vpm450m = init_vpm450m(wc, laws, wc->numspans, firmware))) {
++ dev_notice(&wc->dev->dev, "VPM450: Failed to initialize\n");
++ if (firmware != &embedded_firmware)
++ release_firmware(firmware);
++ return;
++ }
++
++ if (firmware != &embedded_firmware)
++ release_firmware(firmware);
++
++ if (vpmdtmfsupport == -1) {
++ dev_notice(&wc->dev->dev, "VPM450: hardware DTMF disabled.\n");
++ vpmdtmfsupport = 0;
++ }
++
++ wc->vpm = T4_VPM_PRESENT;
++ dev_info(&wc->dev->dev, "VPM450: Present and operational servicing %d "
++ "span(s)\n", wc->numspans);
++
++}
++
++static void t4_vpm400_init(struct t4 *wc)
++{
++ unsigned char reg;
++ unsigned int mask;
++ unsigned int ver;
++ unsigned int i, x, y, gen2vpm=0;
++
++ if (!vpmsupport) {
++ dev_info(&wc->dev->dev, "VPM400: Support Disabled\n");
++ return;
++ }
++
++ switch(vpmspans) {
++ case 4:
++ case 2:
++ case 1:
++ break;
++ default:
++ dev_notice(&wc->dev->dev, "VPM400: %d is not a valid vpmspans "
++ "value, using 4\n", vpmspans);
++ vpmspans = 1;
++ }
++
++ for (x=0;x<8;x++) {
++ int spanno = t4_vpm_spanno(x);
++ struct t4_span *ts = wc->tspans[spanno];
++ int echotail = t4_vpm_echotail();
++
++ ver = t4_vpm_in(wc, x, 0x1a0); /* revision */
++ if ((ver != 0x26) && (ver != 0x33)) {
++ if (x)
++ dev_notice(&wc->dev->dev,
++ "VPM400: Inoperable\n");
++ return;
++ }
++ if (ver == 0x33) {
++ if (x && !gen2vpm) {
++ dev_notice(&wc->dev->dev,
++ "VPM400: Inconsistent\n");
++ return;
++ }
++ ts->spanflags |= FLAG_VPM2GEN;
++ gen2vpm++;
++ } else if (gen2vpm) {
++ dev_notice(&wc->dev->dev,
++ "VPM400: Inconsistent\n");
++ return;
++ }
++
++
++ /* Setup GPIO's */
++ for (y=0;y<4;y++) {
++ t4_vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */
++ t4_vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */
++ t4_vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */
++ }
++
++ /* Setup TDM path - sets fsync and tdm_clk as inputs */
++ reg = t4_vpm_in(wc, x, 0x1a3); /* misc_con */
++ t4_vpm_out(wc, x, 0x1a3, reg & ~2);
++
++ /* Setup timeslots */
++ t4_vpm_out(wc, x, 0x02f, 0x20 | (spanno << 3));
++
++ /* Setup Echo length (128 taps) */
++ t4_vpm_out(wc, x, 0x022, (echotail >> 8));
++ t4_vpm_out(wc, x, 0x023, (echotail & 0xff));
++
++ /* Setup the tdm channel masks for all chips*/
++ mask = t4_vpm_mask(x);
++ for (i = 0; i < 4; i++)
++ t4_vpm_out(wc, x, 0x30 + i, (mask >> (i << 3)) & 0xff);
++
++ /* Setup convergence rate */
++ reg = t4_vpm_in(wc,x,0x20);
++ reg &= 0xE0;
++ if (ts->spantype == TYPE_E1) {
++ if (x < vpmspans)
++ dev_info(&wc->dev->dev, "VPM400: Span %d "
++ "A-law mode\n", spanno);
++ reg |= 0x01;
++ } else {
++ if (x < vpmspans)
++ dev_info(&wc->dev->dev, "VPM400: Span %d "
++ "U-law mode\n", spanno);
++ reg &= ~0x01;
++ }
++ t4_vpm_out(wc,x,0x20,(reg | 0x20));
++
++ /* Initialize echo cans */
++ for (i = 0 ; i < MAX_TDM_CHAN; i++) {
++ if (mask & (0x00000001 << i))
++ t4_vpm_out(wc,x,i,0x00);
++ }
++
++ wait_a_little();
++
++ /* Put in bypass mode */
++ for (i = 0 ; i < MAX_TDM_CHAN ; i++) {
++ if (mask & (0x00000001 << i)) {
++ t4_vpm_out(wc,x,i,0x01);
++ }
++ }
++
++ /* Enable bypass */
++ for (i = 0 ; i < MAX_TDM_CHAN ; i++) {
++ if (mask & (0x00000001 << i))
++ t4_vpm_out(wc,x,0x78 + i,0x01);
++ }
++
++ /* set DTMF detection threshold */
++ t4_vpm_set_dtmf_threshold(wc, dtmfthreshold);
++
++ /* Enable DTMF detectors (always DTMF detect all spans) */
++ for (i = 0; i < MAX_DTMF_DET; i++) {
++ t4_vpm_out(wc, x, 0x98 + i, 0x40 | (i * 2) | ((x < 4) ? 0 : 1));
++ }
++ for (i = 0x34; i < 0x38; i++)
++ t4_vpm_out(wc, x, i, 0x00);
++ for (i = 0x3C; i < 0x40; i++)
++ t4_vpm_out(wc, x, i, 0x00);
++
++ for (i = 0x48; i < 0x4B; i++)
++ t4_vpm_out(wc, x, i, 0x00);
++ for (i = 0x50; i < 0x53; i++)
++ t4_vpm_out(wc, x, i, 0x00);
++ for (i = 0xB8; i < 0xBE; i++)
++ t4_vpm_out(wc, x, i, 0xFF);
++ if (gen2vpm) {
++ for (i = 0xBE; i < 0xC0; i++)
++ t4_vpm_out(wc, x, i, 0xFF);
++ } else {
++ for (i = 0xBE; i < 0xC0; i++)
++ t4_vpm_out(wc, x, i, 0x00);
++ }
++ for (i = 0xC0; i < 0xC4; i++)
++ t4_vpm_out(wc, x, i, (x < 4) ? 0x55 : 0xAA);
++
++ }
++ if (vpmdtmfsupport == -1) {
++ dev_info(&wc->dev->dev, "VPM400: hardware DTMF enabled.\n");
++ vpmdtmfsupport = 0;
++ }
++ dev_info(&wc->dev->dev, "VPM400%s: Present and operational servicing "
++ "%d span(s)\n", (gen2vpm ? " (2nd Gen)" : ""), wc->numspans);
++ wc->vpm = T4_VPM_PRESENT;
++}
++
++#endif
++
++static void t4_tsi_reset(struct t4 *wc)
++{
++ int x;
++ for (x=0;x<128;x++) {
++ wc->dmactrl &= ~0x00007fff;
++ wc->dmactrl |= (0x00004000 | (x << 7));
++ t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++ }
++ wc->dmactrl &= ~0x00007fff;
++ t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++}
++
++/* Note that channels here start from 1 */
++static void t4_tsi_assign(struct t4 *wc, int fromspan, int fromchan, int tospan, int tochan)
++{
++ unsigned long flags;
++ int fromts, tots;
++
++ fromts = (fromspan << 5) |(fromchan);
++ tots = (tospan << 5) | (tochan);
++
++ if (!wc->t1e1) {
++ fromts += 4;
++ tots += 4;
++ }
++ spin_lock_irqsave(&wc->reglock, flags);
++ wc->dmactrl &= ~0x00007fff;
++ wc->dmactrl |= (0x00004000 | (tots << 7) | (fromts));
++ __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++ wc->dmactrl &= ~0x00007fff;
++ __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++}
++
++static void t4_tsi_unassign(struct t4 *wc, int tospan, int tochan)
++{
++ unsigned long flags;
++ int tots;
++
++ tots = (tospan << 5) | (tochan);
++
++ if (!wc->t1e1)
++ tots += 4;
++ spin_lock_irqsave(&wc->reglock, flags);
++ wc->dmactrl &= ~0x00007fff;
++ wc->dmactrl |= (0x00004000 | (tots << 7));
++ __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++ if (debug & DEBUG_TSI)
++ dev_notice(&wc->dev->dev, "Sending '%08x\n", wc->dmactrl);
++ wc->dmactrl &= ~0x00007fff;
++ __t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++}
++#ifdef CONFIG_EXTENDED_RESET
++static void t4_extended_reset(struct t4 *wc)
++{
++ unsigned int oldreg = t4_pci_in(wc, 0x4);
++
++ udelay(1000);
++
++ t4_pci_out(wc, 0x4, 0x42000000);
++ t4_pci_out(wc, 0xa, 0x42000000);
++ t4_pci_out(wc, 0xa, 0x00080000);
++ t4_pci_out(wc, 0xa, 0x00080000);
++ t4_pci_out(wc, 0xa, 0x00080000);
++ t4_pci_out(wc, 0xa, 0x00180000);
++ t4_pci_out(wc, 0xa, 0x00080000);
++ t4_pci_out(wc, 0xa, 0x00180000);
++ t4_pci_out(wc, 0xa, 0x00080000);
++ t4_pci_out(wc, 0xa, 0x00180000);
++ t4_pci_out(wc, 0xa, 0x00080000);
++ t4_pci_out(wc, 0xa, 0x00180000);
++ t4_pci_out(wc, 0xa, 0x00080000);
++ t4_pci_out(wc, 0xa, 0x00180000);
++ t4_pci_out(wc, 0xa, 0x00080000);
++ t4_pci_out(wc, 0xa, 0x00180000);
++ t4_pci_out(wc, 0x4, oldreg);
++
++ udelay(1000);
++}
++#endif
++
++static int t4_hardware_init_1(struct t4 *wc, unsigned int cardflags)
++{
++ unsigned int version;
++
++ version = t4_pci_in(wc, WC_VERSION);
++ dev_info(&wc->dev->dev, "Firmware Version: %08x\n", version);
++ dev_info(&wc->dev->dev, "Burst Mode: %s\n",
++ (!(cardflags & FLAG_BURST) && noburst) ? "Off" : "On");
++#ifdef ENABLE_WORKQUEUES
++ dev_info(&wc->dev->dev, "Work Queues: Enabled\n");
++#endif
++
++#ifdef CONFIG_EXTENDED_RESET
++ t4_extended_reset(wc);
++#endif
++
++ /* Make sure DMA engine is not running and interrupts are acknowledged */
++ wc->dmactrl = 0x0;
++ t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
++ /* Reset Framer and friends */
++ t4_pci_out(wc, WC_LEDS, 0x00000000);
++
++ /* Set DMA addresses */
++ t4_pci_out(wc, WC_RDADDR, wc->readdma);
++ t4_pci_out(wc, WC_WRADDR, wc->writedma);
++
++ /* Setup counters, interrupt flags (ignored in Gen2) */
++ if (cardflags & FLAG_2NDGEN) {
++ t4_tsi_reset(wc);
++ } else {
++ t4_pci_out(wc, WC_COUNT, ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 18) | ((DAHDI_MAX_CHUNKSIZE * 2 * 32 - 1) << 2));
++ }
++
++ /* Reset pending interrupts */
++ t4_pci_out(wc, WC_INTR, 0x00000000);
++
++ /* Read T1/E1 status */
++ if (t1e1override > -1)
++ wc->t1e1 = t1e1override;
++ else
++ wc->t1e1 = ((t4_pci_in(wc, WC_LEDS)) & 0x0f00) >> 8;
++ wc->order = ((t4_pci_in(wc, WC_LEDS)) & 0xf0000000) >> 28;
++ order_index[wc->order]++;
++ return 0;
++}
++
++static int t4_hardware_init_2(struct t4 *wc)
++{
++ int x;
++ unsigned int regval;
++
++ if (t4_pci_in(wc, WC_VERSION) >= 0xc01a0165) {
++ wc->tspans[0]->spanflags |= FLAG_OCTOPT;
++ dev_info(&wc->dev->dev, "Octasic Optimizations: Enabled\n");
++ }
++ /* Setup LEDS, take out of reset */
++ t4_pci_out(wc, WC_LEDS, 0x000000ff);
++ t4_activate(wc);
++
++ /*
++ * In order to find out the QFALC framer version, we have to temporarily term off compat
++ * mode and take a peak at VSTR. We turn compat back on when we are done.
++ */
++ if (t4_framer_in(wc, 0, 0x4a) != 0x05)
++ dev_info(&wc->dev->dev, "WARNING: FALC framer not intialized "
++ "in compatibility mode.\n");
++ regval = t4_framer_in(wc, 0 ,0xd6);
++ regval |= (1 << 5); /* set COMP_DIS*/
++ t4_framer_out(wc, 0, 0xd6, regval);
++ regval = t4_framer_in(wc, 0, 0x4a);
++ if (regval == 0x05)
++ dev_info(&wc->dev->dev, "FALC Framer Version: 2.1 or "
++ "earlier\n");
++ else if (regval == 0x20) {
++ dev_info(&wc->dev->dev, "FALC Framer Version: 3.1\n");
++ wc->falc31 = 1;
++ } else
++ dev_info(&wc->dev->dev, "FALC Framer Version: Unknown "
++ "(VSTR = 0x%02x)\n", regval);
++ regval = t4_framer_in(wc, 0 ,0xd6);
++ regval &= ~(1 << 5); /* clear COMP_DIS*/
++ t4_framer_out(wc, 0, 0xd6, regval);
++
++ t4_framer_out(wc, 0, 0x4a, 0xaa);
++ dev_info(&wc->dev->dev, "Board ID: %02x\n", wc->order);
++
++ for (x=0;x< 11;x++)
++ dev_info(&wc->dev->dev, "Reg %d: 0x%08x\n", x,
++ t4_pci_in(wc, x));
++ return 0;
++}
++
++static int __devinit t4_launch(struct t4 *wc)
++{
++ int x;
++ unsigned long flags;
++ if (test_bit(DAHDI_FLAGBIT_REGISTERED, &wc->tspans[0]->span.flags))
++ return 0;
++ dev_info(&wc->dev->dev, "opvxd115: Launching card: %d\n",
++ wc->order);
++
++ /* Setup serial parameters and system interface */
++ for (x=0;x<PORTS_PER_FRAMER;x++)
++ t4_serial_setup(wc, x);
++
++ for (x = 0; x < wc->numspans; ++x) {
++ list_add_tail(&wc->tspans[x]->span.device_node,
++ &wc->ddev->spans);
++ }
++ if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
++ dev_err(&wc->dev->dev, "Unable to register span %s\n",
++ wc->tspans[0]->span.name);
++ return -1;
++ }
++ set_bit(T4_CHECK_TIMING, &wc->checkflag);
++ spin_lock_irqsave(&wc->reglock, flags);
++ __t4_set_sclk_src(wc, WC_SELF, 0, 0);
++ spin_unlock_irqrestore(&wc->reglock, flags);
++ tasklet_init(&wc->t4_tlet, t4_isr_bh, (unsigned long)wc);
++ return 0;
++}
++
++static void free_wc(struct t4 *wc)
++{
++ unsigned int x, y;
++
++ for (x = 0; x < sizeof(wc->tspans)/sizeof(wc->tspans[0]); x++) {
++ if (!wc->tspans[x]) {
++ continue;
++ }
++
++ for (y = 0; y < sizeof(wc->tspans[x]->chans)/sizeof(wc->tspans[x]->chans[0]); y++) {
++ if (wc->tspans[x]->chans[y]) {
++ kfree(wc->tspans[x]->chans[y]);
++ }
++ if (wc->tspans[x]->ec[y])
++ kfree(wc->tspans[x]->ec[y]);
++ }
++ kfree(wc->tspans[x]);
++ }
++ kfree(wc);
++}
++
++static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
++{
++ struct t4 *wc;
++ struct devtype *dt;
++ unsigned int x, f;
++ int init_latency;
++
++ if (pci_enable_device(pdev)) {
++ return -EIO;
++ }
++
++ if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
++ return -ENOMEM;
++ }
++
++ memset(wc, 0x0, sizeof(*wc));
++ spin_lock_init(&wc->reglock);
++ dt = (struct devtype *) (ent->driver_data);
++
++ wc->flags = dt->flags;
++
++ wc->numspans = 1;
++
++ wc->variety = dt->desc;
++
++ wc->memaddr = pci_resource_start(pdev, 0);
++ wc->memlen = pci_resource_len(pdev, 0);
++ wc->membase = ioremap(wc->memaddr, wc->memlen);
++ /* This rids of the Double missed interrupt message after loading */
++ wc->last0 = 1;
++#if 0
++ if (!request_mem_region(wc->memaddr, wc->memlen, wc->variety))
++ dev_info(&wc->dev->dev, "opvxd115: Unable to request memory "
++ "region :(, using anyway...\n");
++#endif
++ if (pci_request_regions(pdev, wc->variety))
++ dev_info(&pdev->dev, "opvxd115: Unable to request regions\n");
++
++ dev_info(&pdev->dev, "Found opvxd115 at base address %08lx, remapped "
++ "to %p\n", wc->memaddr, wc->membase);
++
++ wc->dev = pdev;
++
++ /* Enable bus mastering */
++ pci_set_master(pdev);
++
++ /* Keep track of which device we are */
++ pci_set_drvdata(pdev, wc);
++
++ if (wc->flags & FLAG_5THGEN) {
++ if ((ms_per_irq > 1) && (latency <= ((ms_per_irq) << 1))) {
++ init_latency = ms_per_irq << 1;
++ } else {
++ if (latency > 2)
++ init_latency = latency;
++ else
++ init_latency = 2;
++ }
++ dev_info(&wc->dev->dev, "5th gen card with initial latency of "
++ "%d and %d ms per IRQ\n", init_latency, ms_per_irq);
++ } else {
++ if (wc->flags & FLAG_2NDGEN)
++ init_latency = 1;
++ else
++ init_latency = 2;
++ }
++
++ if (max_latency < init_latency) {
++ printk(KERN_INFO "maxlatency must be set to something greater than %d ms, increasing it to %d\n", init_latency, init_latency);
++ max_latency = init_latency;
++ }
++
++ if (t4_allocate_buffers(wc, init_latency, NULL, NULL)) {
++ return -ENOMEM;
++ }
++
++ /* Initialize hardware */
++ t4_hardware_init_1(wc, wc->flags);
++
++ for(x = 0; x < MAX_T4_CARDS; x++) {
++ if (!cards[x])
++ break;
++ }
++
++ if (x >= MAX_T4_CARDS) {
++ dev_notice(&wc->dev->dev, "No cards[] slot available!!\n");
++ kfree(wc);
++ return -ENOMEM;
++ }
++
++ wc->num = x;
++ cards[x] = wc;
++
++#ifdef ENABLE_WORKQUEUES
++ if (wc->flags & FLAG_2NDGEN) {
++ char tmp[20];
++
++ sprintf(tmp, "opvxd115");
++ wc->workq = create_workqueue(tmp);
++ }
++#endif
++
++ /* Allocate pieces we need here */
++ for (x = 0; x < PORTS_PER_FRAMER; x++) {
++ if (!(wc->tspans[x] = kmalloc(sizeof(*wc->tspans[x]), GFP_KERNEL))) {
++ free_wc(wc);
++ return -ENOMEM;
++ }
++
++ memset(wc->tspans[x], 0, sizeof(*wc->tspans[x]));
++
++ if (wc->t1e1 & (1 << x)) {
++ wc->tspans[x]->spantype = TYPE_E1;
++ } else {
++ if (j1mode)
++ wc->tspans[x]->spantype = TYPE_J1;
++ else
++ wc->tspans[x]->spantype = TYPE_T1;
++ }
++
++ for (f = 0; f < (wc->tspans[x]->spantype == TYPE_E1 ? 31 : 24); f++) {
++ if (!(wc->tspans[x]->chans[f] = kmalloc(sizeof(*wc->tspans[x]->chans[f]), GFP_KERNEL))) {
++ free_wc(wc);
++ return -ENOMEM;
++ }
++ memset(wc->tspans[x]->chans[f], 0, sizeof(*wc->tspans[x]->chans[f]));
++ if (!(wc->tspans[x]->ec[f] = kmalloc(sizeof(*wc->tspans[x]->ec[f]), GFP_KERNEL))) {
++ free_wc(wc);
++ return -ENOMEM;
++ }
++ memset(wc->tspans[x]->ec[f], 0, sizeof(*wc->tspans[x]->ec[f]));
++ }
++
++#ifdef ENABLE_WORKQUEUES
++ INIT_WORK(&wc->tspans[x]->swork, workq_handlespan, wc->tspans[x]);
++#endif
++ wc->tspans[x]->spanflags |= wc->flags;
++ }
++
++ /* Continue hardware intiialization */
++ t4_hardware_init_2(wc);
++
++#ifdef SUPPORT_GEN1
++ if (request_irq(pdev->irq, (wc->flags & FLAG_2NDGEN) ? t4_interrupt_gen2 :t4_interrupt, IRQF_SHARED | IRQF_DISABLED, "opvxd115", wc))
++#else
++ if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN)) {
++ dev_notice(&wc->dev->dev, "This driver does not "
++ "support 1st gen modules\n");
++ free_wc(wc);
++ return -ENODEV;
++ }
++ if (request_irq(pdev->irq, t4_interrupt_gen2, IRQF_SHARED | IRQF_DISABLED, "opvxd115", wc))
++#endif
++ {
++ dev_notice(&wc->dev->dev, "opvxd115: Unable to request IRQ %d\n",
++ pdev->irq);
++ free_wc(wc);
++ return -EIO;
++ }
++
++ init_spans(wc);
++ /* get the current number of probed cards and run a slice of a tail
++ * insertion sort */
++ for (x = 0; x < MAX_T4_CARDS; x++) {
++ if (!cards[x+1])
++ break;
++ }
++ for ( ; x > 0; x--) {
++ if (cards[x]->order < cards[x-1]->order) {
++ struct t4 *tmp = cards[x];
++ cards[x] = cards[x-1];
++ cards[x-1] = tmp;
++ } else {
++ /* if we're not moving it, we won't move any more
++ * since all cards are sorted on addition */
++ break;
++ }
++ }
++
++ dev_info(&wc->dev->dev, "Found an OpenVox Card: %s\n", wc->variety);
++ wc->gpio = 0x00000000;
++ t4_pci_out(wc, WC_GPIO, wc->gpio);
++ t4_gpio_setdir(wc, (1 << 17), (1 << 17));
++ t4_gpio_setdir(wc, (0xff), (0xff));
++
++ create_sysfs_files(wc);
++
++#if 0
++ for (x=0;x<0x10000;x++) {
++ __t4_raw_oct_out(wc, 0x0004, x);
++ __t4_raw_oct_out(wc, 0x000a, x ^ 0xffff);
++ if (__t4_raw_oct_in(wc, 0x0004) != x)
++ dev_notice(&wc->dev->dev, "Register 4 failed %04x\n",
++ x);
++ if (__t4_raw_oct_in(wc, 0x000a) != (x ^ 0xffff))
++ dev_notice(&wc->dev->dev, "Register 10 failed %04x\n",
++ x);
++ }
++#endif
++
++ return 0;
++}
++
++static int t4_hardware_stop(struct t4 *wc)
++{
++
++ /* Turn off DMA, leave interrupts enabled */
++ set_bit(T4_STOP_DMA, &wc->checkflag);
++
++ /* Wait for interrupts to stop */
++ msleep(25);
++
++ /* Turn off counter, address, etc */
++ if (wc->tspans[0]->spanflags & FLAG_2NDGEN) {
++ t4_tsi_reset(wc);
++ } else {
++ t4_pci_out(wc, WC_COUNT, 0x000000);
++ }
++ t4_pci_out(wc, WC_RDADDR, 0x0000000);
++ t4_pci_out(wc, WC_WRADDR, 0x0000000);
++ wc->gpio = 0x00000000;
++ t4_pci_out(wc, WC_GPIO, wc->gpio);
++ t4_pci_out(wc, WC_LEDS, 0x00000000);
++
++ dev_notice(&wc->dev->dev, "\nStopped opvxd115, Turned off DMA\n");
++ return 0;
++}
++
++static void __devexit t4_remove_one(struct pci_dev *pdev)
++{
++ struct t4 *wc = pci_get_drvdata(pdev);
++ int basesize;
++
++ if (!wc) {
++ return;
++ }
++
++ remove_sysfs_files(wc);
++
++ /* Stop hardware */
++ t4_hardware_stop(wc);
++
++ /* Release vpm450m */
++ if (wc->vpm450m)
++ release_vpm450m(wc->vpm450m);
++ wc->vpm450m = NULL;
++ /* Unregister spans */
++
++ basesize = DAHDI_MAX_CHUNKSIZE * 32 * 4;
++ if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN))
++ basesize = basesize * 2;
++
++ dahdi_unregister_device(wc->ddev);
++ kfree(wc->ddev->location);
++ kfree(wc->ddev->devicetype);
++ dahdi_free_device(wc->ddev);
++#ifdef ENABLE_WORKQUEUES
++ if (wc->workq) {
++ flush_workqueue(wc->workq);
++ destroy_workqueue(wc->workq);
++ }
++#endif
++
++ free_irq(pdev->irq, wc);
++
++ if (wc->membase)
++ iounmap(wc->membase);
++
++ pci_release_regions(pdev);
++
++ /* Immediately free resources */
++ pci_free_consistent(pdev, T4_BASE_SIZE * wc->numbufs * 2, (void *)wc->writechunk, wc->writedma);
++
++ order_index[wc->order]--;
++
++ cards[wc->num] = NULL;
++ pci_set_drvdata(pdev, NULL);
++ free_wc(wc);
++}
++
++
++static struct pci_device_id t4_pci_tbl[] __devinitdata =
++{
++ { 0x1b74, 0x0115, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&opvxd115 }, /* OpenVox D115P/D115E */
++ { 0x1b74, 0xd130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&opvxd130 }, /* OpenVox D130P/D130E */
++ { 0, }
++};
++
++static struct pci_driver t4_driver = {
++ .name = "opvxd115",
++ .probe = t4_init_one,
++ .remove = __devexit_p(t4_remove_one),
++ .id_table = t4_pci_tbl,
++};
++
++static int __init t4_init(void)
++{
++ int res;
++ res = pci_register_driver(&t4_driver);
++ if (res)
++ return -ENODEV;
++ /* initialize cards since we have all of them */
++ /* warn for missing zero and duplicate numbers */
++ if (cards[0] && cards[0]->order != 0) {
++ printk(KERN_NOTICE "opvxd115: Ident of first card is not zero (%d)\n",
++ cards[0]->order);
++ }
++ for (res = 0; cards[res]; res++) {
++ /* warn the user of duplicate ident values it is probably
++ * unintended */
++ if (debug && res < 15 && cards[res+1] &&
++ cards[res]->order == cards[res+1]->order) {
++ printk(KERN_NOTICE "opvxd115: Duplicate ident value found (%d)\n",
++ cards[res]->order);
++ }
++ t4_launch(cards[res]);
++ }
++ return 0;
++}
++
++static void __exit t4_cleanup(void)
++{
++ pci_unregister_driver(&t4_driver);
++}
++
++
++MODULE_AUTHOR("mark.liu <mark.liu@openvox.cn>");
++MODULE_DESCRIPTION("Unified OpenVox Single T1/E1/J1 Card Driver");
++MODULE_ALIAS("opvxd115");
++MODULE_LICENSE("GPL v2");
++
++module_param(pedanticpci, int, 0600);
++module_param(debug, int, 0600);
++module_param(noburst, int, 0600);
++module_param(timingcable, int, 0600);
++module_param(t1e1override, int, 0600);
++module_param(alarmdebounce, int, 0600);
++module_param(losalarmdebounce, int, 0600);
++module_param(aisalarmdebounce, int, 0600);
++module_param(yelalarmdebounce, int, 0600);
++module_param(max_latency, int, 0600);
++module_param(j1mode, int, 0600);
++module_param(sigmode, int, 0600);
++module_param(latency, int, 0600);
++module_param(ms_per_irq, int, 0600);
++#ifdef VPM_SUPPORT
++module_param(vpmsupport, int, 0600);
++module_param(vpmdtmfsupport, int, 0600);
++module_param(vpmspans, int, 0600);
++module_param(dtmfthreshold, int, 0600);
++#endif
++
++MODULE_DEVICE_TABLE(pci, t4_pci_tbl);
++
++module_init(t4_init);
++module_exit(t4_cleanup);
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/opvxd115/Kbuild dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/Kbuild
+--- dahdi-linux-2.7.0/drivers/dahdi/opvxd115/Kbuild 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/Kbuild 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,32 @@
++obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OPVXD115) += opvxd115.o
++
++FIRM_DIR := ../firmware
++
++EXTRA_CFLAGS += -I$(src)/.. $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
++
++ifeq ($(HOTPLUG_FIRMWARE),yes)
++ EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE
++endif
++
++opvxd115-objs := base.o vpm450m.o
++
++DAHDI_KERNEL_H_NAME:=kernel.h
++DAHDI_KERNEL_H_PATH:=$(DAHDI_INCLUDE)/dahdi/$(DAHDI_KERNEL_H_NAME)
++ifneq ($(DAHDI_KERNEL_H_PATH),)
++ DAHDI_SPAN_MODULE:=$(shell if grep -C 5 "struct dahdi_span {" $(DAHDI_KERNEL_H_PATH) | grep -q "struct module \*owner"; then echo "yes"; else echo "no"; fi)
++ DAHDI_SPAN_OPS:=$(shell if grep -q "struct dahdi_span_ops {" $(DAHDI_KERNEL_H_PATH); then echo "yes"; else echo "no"; fi)
++ ifeq ($(DAHDI_SPAN_MODULE),yes)
++ EXTRA_CFLAGS+=-DDAHDI_SPAN_MODULE
++ else
++ ifeq ($(DAHDI_SPAN_OPS),yes)
++ EXTRA_CFLAGS+=-DDAHDI_SPAN_OPS
++ endif
++ endif
++endif
++
++ifneq ($(HOTPLUG_FIRMWARE),yes)
++opvxd115-objs += $(FIRM_DIR)/dahdi-fw-oct6114-032.o
++endif
++
++$(obj)/$(FIRM_DIR)/dahdi-fw-oct6114-032.o: $(obj)/base.o
++ $(MAKE) -C $(obj)/$(FIRM_DIR) dahdi-fw-oct6114-032.o
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/opvxd115/Makefile dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/Makefile
+--- dahdi-linux-2.7.0/drivers/dahdi/opvxd115/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/Makefile 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,8 @@
++ifdef KBUILD_EXTMOD
++# We only get here on kernels 2.6.0-2.6.9 .
++# For newer kernels, Kbuild will be included directly by the kernel
++# build system.
++include $(src)/Kbuild
++
++else
++endif
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/opvxd115/opvxd115-diag.c dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/opvxd115-diag.c
+--- dahdi-linux-2.7.0/drivers/dahdi/opvxd115/opvxd115-diag.c 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/opvxd115-diag.c 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,427 @@
++/*
++ * See http://www.asterisk.org for more information about
++ * the Asterisk project. Please do not directly contact
++ * any of the maintainers of this project for assistance;
++ * the project provides a web site, mailing lists and IRC
++ * channels for your use.
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License Version 2 as published by the
++ * Free Software Foundation. See the LICENSE file included with
++ * this program for more details.
++ */
++
++#include <fcntl.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/ioctl.h>
++#include <errno.h>
++#include <string.h>
++#include <dahdi/user.h>
++#include "opvxd115.h"
++
++struct t4_reg_def {
++ int reg;
++ char *name;
++ int global;
++};
++static struct t4_reg_def xreginfo[] = {
++ { 0x00, "RDADDR" },
++ { 0x01, "WRADDR" },
++ { 0x02, "COUNT" },
++ { 0x03, "DMACTRL" },
++ { 0x04, "WCINTR" },
++ { 0x06, "VERSION" },
++ { 0x07, "LEDS" },
++ { 0x08, "GPIOCTL" },
++ { 0x09, "GPIO" },
++ { 0x0A, "LADDR" },
++ { 0x0b, "LDATA" },
++};
++
++static struct t4_reg_def reginfo[] = {
++ { 0x00, "XFIFO" },
++ { 0x01, "XFIFO" },
++ { 0x02, "CMDR" },
++ { 0x03, "MODE" },
++ { 0x04, "RAH1" },
++ { 0x05, "RAH2" },
++ { 0x06, "RAL1" },
++ { 0x07, "RAL2" },
++ { 0x08, "IPC", 1 },
++ { 0x09, "CCR1" },
++ { 0x0a, "CCR2" },
++ { 0x0c, "RTR1" },
++ { 0x0d, "RTR2" },
++ { 0x0e, "RTR3" },
++ { 0x0f, "RTR4" },
++ { 0x10, "TTR1" },
++ { 0x11, "TTR2" },
++ { 0x12, "TTR3" },
++ { 0x13, "TTR4" },
++ { 0x14, "IMR0" },
++ { 0x15, "IMR1" },
++ { 0x16, "IMR2" },
++ { 0x17, "IMR3" },
++ { 0x18, "IMR4" },
++ { 0x1b, "IERR" },
++ { 0x1c, "FMR0" },
++ { 0x1d, "FMR1" },
++ { 0x1e, "FMR2" },
++ { 0x1f, "LOOP" },
++ { 0x20, "XSW" },
++ { 0x21, "XSP" },
++ { 0x22, "XC0" },
++ { 0x23, "XC1" },
++ { 0x24, "RC0" },
++ { 0x25, "RC1" },
++ { 0x26, "XPM0" },
++ { 0x27, "XPM1" },
++ { 0x28, "XPM2" },
++ { 0x29, "TSWM" },
++ { 0x2b, "IDLE" },
++ { 0x2c, "XSA4" },
++ { 0x2d, "XSA5" },
++ { 0x2e, "XSA6" },
++ { 0x2f, "XSA7" },
++ { 0x30, "XSA8" },
++ { 0x31, "FMR3" },
++ { 0x32, "ICB1" },
++ { 0x33, "ICB2" },
++ { 0x34, "ICB3" },
++ { 0x35, "ICB4" },
++ { 0x36, "LIM0" },
++ { 0x37, "LIM1" },
++ { 0x38, "PCD" },
++ { 0x39, "PCR" },
++ { 0x3a, "LIM2" },
++ { 0x3b, "LCR1" },
++ { 0x3c, "LCR2" },
++ { 0x3d, "LCR3" },
++ { 0x3e, "SIC1" },
++ { 0x3f, "SIC2" },
++ { 0x40, "SIC3" },
++ { 0x44, "CMR1" },
++ { 0x45, "CMR2" },
++ { 0x46, "GCR" },
++ { 0x47, "ESM" },
++ { 0x60, "DEC" },
++ { 0x70, "XS1" },
++ { 0x71, "XS2" },
++ { 0x72, "XS3" },
++ { 0x73, "XS4" },
++ { 0x74, "XS5" },
++ { 0x75, "XS6" },
++ { 0x76, "XS7" },
++ { 0x77, "XS8" },
++ { 0x78, "XS9" },
++ { 0x79, "XS10" },
++ { 0x7a, "XS11" },
++ { 0x7b, "XS12" },
++ { 0x7c, "XS13" },
++ { 0x7d, "XS14" },
++ { 0x7e, "XS15" },
++ { 0x7f, "XS16" },
++ { 0x80, "PC1" },
++ { 0x81, "PC2" },
++ { 0x82, "PC3" },
++ { 0x83, "PC4" },
++ { 0x84, "PC5" },
++ { 0x85, "GPC1", 1 },
++ { 0x87, "CMDR2" },
++ { 0x8d, "CCR5" },
++ { 0x92, "GCM1", 1 },
++ { 0x93, "GCM2", 1 },
++ { 0x94, "GCM3", 1 },
++ { 0x95, "GCM4", 1 },
++ { 0x96, "GCM5", 1 },
++ { 0x97, "GCM6", 1 },
++ { 0x98, "GCM7", 1 },
++ { 0x99, "GCM8", 1 },
++ { 0xa0, "TSEO" },
++ { 0xa1, "TSBS1" },
++ { 0xa8, "TPC0" },
++};
++
++static struct t4_reg_def t1_reginfo[] = {
++ { 0x00, "XFIFO" },
++ { 0x01, "XFIFO" },
++ { 0x02, "CMDR" },
++ { 0x03, "MODE" },
++ { 0x04, "RAH1" },
++ { 0x05, "RAH2" },
++ { 0x06, "RAL1" },
++ { 0x07, "RAL2" },
++ { 0x08, "IPC", 1 },
++ { 0x09, "CCR1" },
++ { 0x0a, "CCR2" },
++ { 0x0c, "RTR1" },
++ { 0x0d, "RTR2" },
++ { 0x0e, "RTR3" },
++ { 0x0f, "RTR4" },
++ { 0x10, "TTR1" },
++ { 0x11, "TTR2" },
++ { 0x12, "TTR3" },
++ { 0x13, "TTR4" },
++ { 0x14, "IMR0" },
++ { 0x15, "IMR1" },
++ { 0x16, "IMR2" },
++ { 0x17, "IMR3" },
++ { 0x18, "IMR4" },
++ { 0x1b, "IERR" },
++ { 0x1c, "FMR0" },
++ { 0x1d, "FMR1" },
++ { 0x1e, "FMR2" },
++ { 0x1f, "LOOP" },
++ { 0x20, "FMR4" },
++ { 0x21, "FMR5" },
++ { 0x22, "XC0" },
++ { 0x23, "XC1" },
++ { 0x24, "RC0" },
++ { 0x25, "RC1" },
++ { 0x26, "XPM0" },
++ { 0x27, "XPM1" },
++ { 0x28, "XPM2" },
++ { 0x2b, "IDLE" },
++ { 0x2c, "XDL1" },
++ { 0x2d, "XDL2" },
++ { 0x2e, "XDL3" },
++ { 0x2f, "CCB1" },
++ { 0x30, "CCB2" },
++ { 0x31, "CCB3" },
++ { 0x32, "ICB1" },
++ { 0x33, "ICB2" },
++ { 0x34, "ICB3" },
++ { 0x36, "LIM0" },
++ { 0x37, "LIM1" },
++ { 0x38, "PCD" },
++ { 0x39, "PCR" },
++ { 0x3a, "LIM2" },
++ { 0x3b, "LCR1" },
++ { 0x3c, "LCR2" },
++ { 0x3d, "LCR3" },
++ { 0x3e, "SIC1" },
++ { 0x3f, "SIC2" },
++ { 0x40, "SIC3" },
++ { 0x44, "CMR1" },
++ { 0x45, "CMR2" },
++ { 0x46, "GCR" },
++ { 0x47, "ESM" },
++ { 0x60, "DEC" },
++ { 0x70, "XS1" },
++ { 0x71, "XS2" },
++ { 0x72, "XS3" },
++ { 0x73, "XS4" },
++ { 0x74, "XS5" },
++ { 0x75, "XS6" },
++ { 0x76, "XS7" },
++ { 0x77, "XS8" },
++ { 0x78, "XS9" },
++ { 0x79, "XS10" },
++ { 0x7a, "XS11" },
++ { 0x7b, "XS12" },
++ { 0x80, "PC1" },
++ { 0x81, "PC2" },
++ { 0x82, "PC3" },
++ { 0x83, "PC4" },
++ { 0x84, "PC5" },
++ { 0x85, "GPC1", 1 },
++ { 0x87, "CMDR2" },
++ { 0x8d, "CCR5" },
++ { 0x92, "GCM1", 1 },
++ { 0x93, "GCM2", 1 },
++ { 0x94, "GCM3", 1 },
++ { 0x95, "GCM4", 1 },
++ { 0x96, "GCM5", 1 },
++ { 0x97, "GCM6", 1 },
++ { 0x98, "GCM7", 1 },
++ { 0x99, "GCM8", 1 },
++ { 0xa0, "TSEO" },
++ { 0xa1, "TSBS1" },
++ { 0xa8, "TPC0" },
++};
++
++static struct t4_reg_def t1_sreginfo[] = {
++ { 0x00, "RFIFO" },
++ { 0x01, "RFIFO" },
++ { 0x49, "RBD" },
++ { 0x4a, "VSTR", 1 },
++ { 0x4b, "RES" },
++ { 0x4c, "FRS0" },
++ { 0x4d, "FRS1" },
++ { 0x4e, "FRS2" },
++ { 0x4f, "Old FRS1" },
++ { 0x50, "FECL" },
++ { 0x51, "FECH" },
++ { 0x52, "CVCL" },
++ { 0x53, "CVCH" },
++ { 0x54, "CECL" },
++ { 0x55, "CECH" },
++ { 0x56, "EBCL" },
++ { 0x57, "EBCH" },
++ { 0x58, "BECL" },
++ { 0x59, "BECH" },
++ { 0x5a, "COEC" },
++ { 0x5c, "RDL1" },
++ { 0x5d, "RDL2" },
++ { 0x5e, "RDL3" },
++ { 0x62, "RSP1" },
++ { 0x63, "RSP2" },
++ { 0x64, "SIS" },
++ { 0x65, "RSIS" },
++ { 0x66, "RBCL" },
++ { 0x67, "RBCH" },
++ { 0x68, "ISR0" },
++ { 0x69, "ISR1" },
++ { 0x6a, "ISR2" },
++ { 0x6b, "ISR3" },
++ { 0x6c, "ISR4" },
++ { 0x6e, "GIS" },
++ { 0x6f, "CIS", 1 },
++ { 0x70, "RS1" },
++ { 0x71, "RS2" },
++ { 0x72, "RS3" },
++ { 0x73, "RS4" },
++ { 0x74, "RS5" },
++ { 0x75, "RS6" },
++ { 0x76, "RS7" },
++ { 0x77, "RS8" },
++ { 0x78, "RS9" },
++ { 0x79, "RS10" },
++ { 0x7a, "RS11" },
++ { 0x7b, "RS12" },
++};
++
++static struct t4_reg_def sreginfo[] = {
++ { 0x00, "RFIFO" },
++ { 0x01, "RFIFO" },
++ { 0x49, "RBD" },
++ { 0x4a, "VSTR", 1 },
++ { 0x4b, "RES" },
++ { 0x4c, "FRS0" },
++ { 0x4d, "FRS1" },
++ { 0x4e, "RSW" },
++ { 0x4f, "RSP" },
++ { 0x50, "FECL" },
++ { 0x51, "FECH" },
++ { 0x52, "CVCL" },
++ { 0x53, "CVCH" },
++ { 0x54, "CEC1L" },
++ { 0x55, "CEC1H" },
++ { 0x56, "EBCL" },
++ { 0x57, "EBCH" },
++ { 0x58, "CEC2L" },
++ { 0x59, "CEC2H" },
++ { 0x5a, "CEC3L" },
++ { 0x5b, "CEC3H" },
++ { 0x5c, "RSA4" },
++ { 0x5d, "RSA5" },
++ { 0x5e, "RSA6" },
++ { 0x5f, "RSA7" },
++ { 0x60, "RSA8" },
++ { 0x61, "RSA6S" },
++ { 0x62, "RSP1" },
++ { 0x63, "RSP2" },
++ { 0x64, "SIS" },
++ { 0x65, "RSIS" },
++ { 0x66, "RBCL" },
++ { 0x67, "RBCH" },
++ { 0x68, "ISR0" },
++ { 0x69, "ISR1" },
++ { 0x6a, "ISR2" },
++ { 0x6b, "ISR3" },
++ { 0x6c, "ISR4" },
++ { 0x6e, "GIS" },
++ { 0x6f, "CIS", 1 },
++ { 0x70, "RS1" },
++ { 0x71, "RS2" },
++ { 0x72, "RS3" },
++ { 0x73, "RS4" },
++ { 0x74, "RS5" },
++ { 0x75, "RS6" },
++ { 0x76, "RS7" },
++ { 0x77, "RS8" },
++ { 0x78, "RS9" },
++ { 0x79, "RS10" },
++ { 0x7a, "RS11" },
++ { 0x7b, "RS12" },
++ { 0x7c, "RS13" },
++ { 0x7d, "RS14" },
++ { 0x7e, "RS15" },
++ { 0x7f, "RS16" },
++};
++
++static char *tobin(int x)
++{
++ static char s[9] = "";
++ int y,z=0;
++ for (y=7;y>=0;y--) {
++ if (x & (1 << y))
++ s[z++] = '1';
++ else
++ s[z++] = '0';
++ }
++ s[z] = '\0';
++ return s;
++}
++
++static char *tobin32(unsigned int x)
++{
++ static char s[33] = "";
++ int y,z=0;
++ for (y=31;y>=0;y--) {
++ if (x & (1 << y))
++ s[z++] = '1';
++ else
++ s[z++] = '0';
++ }
++ s[z] = '\0';
++ return s;
++}
++
++int main(int argc, char *argv[])
++{
++ int fd;
++ int x;
++ char fn[256];
++ struct t4_regs regs;
++ if ((argc < 2) || ((*(argv[1]) != '/') && !atoi(argv[1]))) {
++ fprintf(stderr, "Usage: opvxd115-diag <channel>\n");
++ exit(1);
++ }
++ if (*(argv[1]) == '/')
++ dahdi_copy_string(fn, argv[1], sizeof(fn));
++ else
++ snprintf(fn, sizeof(fn), "/dev/dahdi/%d", atoi(argv[1]));
++ fd = open(fn, O_RDWR);
++ if (fd <0) {
++ fprintf(stderr, "Unable to open '%s': %s\n", fn, strerror(errno));
++ exit(1);
++ }
++ if (ioctl(fd, WCT4_GET_REGS, &regs)) {
++ fprintf(stderr, "Unable to get registers: %s\n", strerror(errno));
++ exit(1);
++ }
++ printf("PCI Registers:\n");
++ for (x=0;x<sizeof(xreginfo) / sizeof(xreginfo[0]);x++) {
++ fprintf(stdout, "%s (%02x): %08x (%s)\n", xreginfo[x].name, xreginfo[x].reg, regs.pci[xreginfo[x].reg], tobin32(regs.pci[xreginfo[x].reg]));
++ }
++ printf("\nE1 Control Registers:\n");
++ for (x=0;x<sizeof(reginfo) / sizeof(reginfo[0]);x++) {
++ fprintf(stdout, "%s (%02x): %02x (%s)\n", reginfo[x].name, reginfo[x].reg, regs.regs[reginfo[x].reg], tobin(regs.regs[reginfo[x].reg]));
++ }
++ printf("\nE1 Status Registers:\n");
++ for (x=0;x<sizeof(sreginfo) / sizeof(sreginfo[0]);x++) {
++ fprintf(stdout, "%s (%02x): %02x (%s)\n", sreginfo[x].name, sreginfo[x].reg, regs.regs[sreginfo[x].reg], tobin(regs.regs[sreginfo[x].reg]));
++ }
++ printf("\nT1 Control Registers:\n");
++ for (x=0;x<sizeof(t1_reginfo) / sizeof(t1_reginfo[0]);x++) {
++ fprintf(stdout, "%s (%02x): %02x (%s)\n", t1_reginfo[x].name, t1_reginfo[x].reg, regs.regs[t1_reginfo[x].reg], tobin(regs.regs[t1_reginfo[x].reg]));
++ }
++ printf("\nT1 Status Registers:\n");
++ for (x=0;x<sizeof(t1_sreginfo) / sizeof(t1_sreginfo[0]);x++) {
++ fprintf(stdout, "%s (%02x): %02x (%s)\n", t1_sreginfo[x].name, t1_sreginfo[x].reg, regs.regs[t1_sreginfo[x].reg], tobin(regs.regs[t1_sreginfo[x].reg]));
++ }
++ exit(0);
++}
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/opvxd115/opvxd115.h dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/opvxd115.h
+--- dahdi-linux-2.7.0/drivers/dahdi/opvxd115/opvxd115.h 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/opvxd115.h 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,124 @@
++/*
++ * Wildcard T400P FXS Interface Driver for DAHDI Telephony interface
++ *
++ * Written by Mark Spencer <markster@linux-support.net>
++ *
++ * Copyright (C) 2001-2008, Digium, Inc.
++ *
++ * All rights reserved.
++ *
++ */
++
++/*
++ * See http://www.asterisk.org for more information about
++ * the Asterisk project. Please do not directly contact
++ * any of the maintainers of this project for assistance;
++ * the project provides a web site, mailing lists and IRC
++ * channels for your use.
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License Version 2 as published by the
++ * Free Software Foundation. See the LICENSE file included with
++ * this program for more details.
++ */
++
++#include <linux/ioctl.h>
++
++#define FRMR_TTR_BASE 0x10
++#define FRMR_RTR_BASE 0x0c
++#define FRMR_TSEO 0xa0
++#define FRMR_TSBS1 0xa1
++#define FRMR_CCR1 0x09
++#define FRMR_CCR1_ITF 0x08
++#define FRMR_CCR1_EITS 0x10
++#define FRMR_CCR2 0x0a
++#define FRMR_CCR2_RCRC 0x04
++#define FRMR_CCR2_RADD 0x10
++#define FRMR_MODE 0x03
++#define FRMR_MODE_NO_ADDR_CMP 0x80
++#define FRMR_MODE_SS7 0x20
++#define FRMR_MODE_HRAC 0x08
++#define FRMR_IMR0 0x14
++#define FRMR_IMR0_RME 0x80
++#define FRMR_IMR0_RPF 0x01
++#define FRMR_IMR1 0x15
++#define FRMR_IMR1_ALLS 0x20
++#define FRMR_IMR1_XDU 0x10
++#define FRMR_IMR1_XPR 0x01
++#define FRMR_XC0 0x22
++#define FRMR_XC1 0x23
++#define FRMR_RC0 0x24
++#define FRMR_RC1 0x25
++#define FRMR_SIC1 0x3e
++#define FRMR_SIC2 0x3f
++#define FRMR_SIC3 0x40
++#define FRMR_CMR1 0x44
++#define FRMR_CMR2 0x45
++#define FRMR_GCR 0x46
++#define FRMR_ISR0 0x68
++#define FRMR_ISR0_RME 0x80
++#define FRMR_ISR0_RPF 0x01
++#define FRMR_ISR1 0x69
++#define FRMR_ISR1_ALLS 0x20
++#define FRMR_ISR1_XDU 0x10
++#define FRMR_ISR1_XPR 0x01
++#define FRMR_ISR2 0x6a
++#define FRMR_ISR3 0x6b
++#define FRMR_ISR4 0x6c
++#define FRMR_GIS 0x6e
++#define FRMR_GIS_ISR0 0x01
++#define FRMR_GIS_ISR1 0x02
++#define FRMR_GIS_ISR2 0x04
++#define FRMR_GIS_ISR3 0x08
++#define FRMR_GIS_ISR4 0x10
++#define FRMR_CIS 0x6f
++#define FRMR_CIS_GIS1 0x01
++#define FRMR_CIS_GIS2 0x02
++#define FRMR_CIS_GIS3 0x04
++#define FRMR_CIS_GIS4 0x08
++#define FRMR_CMDR 0x02
++#define FRMR_CMDR_SRES 0x01
++#define FRMR_CMDR_XRES 0x10
++#define FRMR_CMDR_RMC 0x80
++#define FRMR_CMDR_XTF 0x04
++#define FRMR_CMDR_XHF 0x08
++#define FRMR_CMDR_XME 0x02
++#define FRMR_RSIS 0x65
++#define FRMR_RSIS_VFR 0x80
++#define FRMR_RSIS_RDO 0x40
++#define FRMR_RSIS_CRC16 0x20
++#define FRMR_RSIS_RAB 0x10
++#define FRMR_RBCL 0x66
++#define FRMR_RBCL_MAX_SIZE 0x1f
++#define FRMR_RBCH 0x67
++#define FRMR_RXFIFO 0x00
++#define FRMR_SIS 0x64
++#define FRMR_SIS_XFW 0x40
++#define FRMR_TXFIFO 0x00
++
++#define FRS0 0x4c
++#define FRS0_LOS (1<<7)
++#define FRS0_LFA (1<<5)
++#define FRS0_LMFA (1<<1)
++
++#define FRS1 0x4d
++#define FRS1_XLS (1<<1)
++#define FRS1_XLO (1<<0)
++
++#define NUM_REGS 0xa9
++#define NUM_PCI 12
++
++struct t4_regs {
++ unsigned int pci[NUM_PCI];
++ unsigned char regs[NUM_REGS];
++};
++
++#define T4_CHECK_VPM 0
++#define T4_LOADING_FW 1
++#define T4_STOP_DMA 2
++#define T4_CHECK_TIMING 3
++#define T4_CHANGE_LATENCY 4
++#define T4_IGNORE_LATENCY 5
++
++#define WCT4_GET_REGS _IOW (DAHDI_CODE, 60, struct t4_regs)
++
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/opvxd115/vpm450m.c dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/vpm450m.c
+--- dahdi-linux-2.7.0/drivers/dahdi/opvxd115/vpm450m.c 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/vpm450m.c 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,597 @@
++/*
++ * Copyright (C) 2005-2006 Digium, Inc.
++ *
++ * Mark Spencer <markster@digium.com>
++ * Modified by mark.liu@openvox.cn 06/16/2009
++
++ * All Rights Reserved
++ */
++
++/*
++ * See http://www.asterisk.org for more information about
++ * the Asterisk project. Please do not directly contact
++ * any of the maintainers of this project for assistance;
++ * the project provides a web site, mailing lists and IRC
++ * channels for your use.
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License Version 2 as published by the
++ * Free Software Foundation. See the LICENSE file included with
++ * this program for more details.
++ */
++
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/string.h>
++#include <linux/time.h>
++#include <linux/version.h>
++
++#include "vpm450m.h"
++#include "oct6100api/oct6100_api.h"
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
++#include <linux/config.h>
++#endif
++
++/* API for Octasic access */
++UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
++{
++ /* Why couldn't they just take a timeval like everyone else? */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5,0,0)
++ struct timeval tv;
++#else
++ struct timespec64 tv;
++#endif
++ unsigned long long total_usecs;
++ unsigned int mask = ~0;
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0)
++ do_gettimeofday(&tv);
++ total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
++ (((unsigned long long)(tv.tv_usec)));
++#else
++ ktime_get_real_ts64(&tv);
++ total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
++ (((unsigned long long)(tv.tv_nsec))) / 1000;
++#endif
++ f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
++ f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength)
++{
++ memset(f_pAddress, f_ulPattern, f_ulLength);
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength)
++{
++ memcpy(f_pDestination, f_pSource, f_ulLength);
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
++{
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
++{
++#ifdef OCTASIC_DEBUG
++ printk(KERN_DEBUG "I should never be called! (destroy serialize object)\n");
++#endif
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
++{
++ /* Not needed */
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
++{
++ /* Not needed */
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
++{
++ oct_set_reg(f_pWriteParams->pProcessContext, f_pWriteParams->ulWriteAddress, f_pWriteParams->usWriteData);
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
++{
++ unsigned int x;
++ for (x=0;x<f_pSmearParams->ulWriteLength;x++) {
++ oct_set_reg(f_pSmearParams->pProcessContext, f_pSmearParams->ulWriteAddress + (x << 1), f_pSmearParams->usWriteData);
++ }
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
++{
++ unsigned int x;
++ for (x=0;x<f_pBurstParams->ulWriteLength;x++) {
++ oct_set_reg(f_pBurstParams->pProcessContext, f_pBurstParams->ulWriteAddress + (x << 1), f_pBurstParams->pusWriteData[x]);
++ }
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
++{
++ *(f_pReadParams->pusReadData) = oct_get_reg(f_pReadParams->pProcessContext, f_pReadParams->ulReadAddress);
++ return cOCT6100_ERR_OK;
++}
++
++UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
++{
++ unsigned int x;
++ for (x=0;x<f_pBurstParams->ulReadLength;x++) {
++ f_pBurstParams->pusReadData[x] = oct_get_reg(f_pBurstParams->pProcessContext, f_pBurstParams->ulReadAddress + (x << 1));
++ }
++ return cOCT6100_ERR_OK;
++}
++
++#define SOUT_G168_1100GB_ON 0x40000004
++#define SOUT_DTMF_1 0x40000011
++#define SOUT_DTMF_2 0x40000012
++#define SOUT_DTMF_3 0x40000013
++#define SOUT_DTMF_A 0x4000001A
++#define SOUT_DTMF_4 0x40000014
++#define SOUT_DTMF_5 0x40000015
++#define SOUT_DTMF_6 0x40000016
++#define SOUT_DTMF_B 0x4000001B
++#define SOUT_DTMF_7 0x40000017
++#define SOUT_DTMF_8 0x40000018
++#define SOUT_DTMF_9 0x40000019
++#define SOUT_DTMF_C 0x4000001C
++#define SOUT_DTMF_STAR 0x4000001E
++#define SOUT_DTMF_0 0x40000010
++#define SOUT_DTMF_POUND 0x4000001F
++#define SOUT_DTMF_D 0x4000001D
++
++#define ROUT_G168_2100GB_ON 0x10000000
++#define ROUT_G168_2100GB_WSPR 0x10000002
++#define ROUT_SOUT_G168_2100HB_END 0x50000003
++#define ROUT_G168_1100GB_ON 0x10000004
++
++#define ROUT_DTMF_1 0x10000011
++#define ROUT_DTMF_2 0x10000012
++#define ROUT_DTMF_3 0x10000013
++#define ROUT_DTMF_A 0x1000001A
++#define ROUT_DTMF_4 0x10000014
++#define ROUT_DTMF_5 0x10000015
++#define ROUT_DTMF_6 0x10000016
++#define ROUT_DTMF_B 0x1000001B
++#define ROUT_DTMF_7 0x10000017
++#define ROUT_DTMF_8 0x10000018
++#define ROUT_DTMF_9 0x10000019
++#define ROUT_DTMF_C 0x1000001C
++#define ROUT_DTMF_STAR 0x1000001E
++#define ROUT_DTMF_0 0x10000010
++#define ROUT_DTMF_POUND 0x1000001F
++#define ROUT_DTMF_D 0x1000001D
++
++#if 0
++#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_HT_FREEZE
++#else
++#define cOCT6100_ECHO_OP_MODE_DIGITAL cOCT6100_ECHO_OP_MODE_POWER_DOWN
++#endif
++
++struct vpm450m {
++ tPOCT6100_INSTANCE_API pApiInstance;
++ UINT32 aulEchoChanHndl[ 128 ];
++ int chanflags[128];
++ int ecmode[128];
++ int numchans;
++};
++
++#define FLAG_DTMF (1 << 0)
++#define FLAG_MUTE (1 << 1)
++#define FLAG_ECHO (1 << 2)
++
++static unsigned int tones[] = {
++ SOUT_DTMF_1,
++ SOUT_DTMF_2,
++ SOUT_DTMF_3,
++ SOUT_DTMF_A,
++ SOUT_DTMF_4,
++ SOUT_DTMF_5,
++ SOUT_DTMF_6,
++ SOUT_DTMF_B,
++ SOUT_DTMF_7,
++ SOUT_DTMF_8,
++ SOUT_DTMF_9,
++ SOUT_DTMF_C,
++ SOUT_DTMF_STAR,
++ SOUT_DTMF_0,
++ SOUT_DTMF_POUND,
++ SOUT_DTMF_D,
++ SOUT_G168_1100GB_ON,
++
++ ROUT_DTMF_1,
++ ROUT_DTMF_2,
++ ROUT_DTMF_3,
++ ROUT_DTMF_A,
++ ROUT_DTMF_4,
++ ROUT_DTMF_5,
++ ROUT_DTMF_6,
++ ROUT_DTMF_B,
++ ROUT_DTMF_7,
++ ROUT_DTMF_8,
++ ROUT_DTMF_9,
++ ROUT_DTMF_C,
++ ROUT_DTMF_STAR,
++ ROUT_DTMF_0,
++ ROUT_DTMF_POUND,
++ ROUT_DTMF_D,
++ ROUT_G168_1100GB_ON,
++};
++
++static void vpm450m_setecmode(struct vpm450m *vpm450m, int channel, int mode)
++{
++ tOCT6100_CHANNEL_MODIFY *modify;
++ UINT32 ulResult;
++
++ if (vpm450m->ecmode[channel] == mode)
++ return;
++ modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_ATOMIC);
++ if (!modify) {
++ printk(KERN_NOTICE "opvxd115: Unable to allocate memory for setec!\n");
++ return;
++ }
++ Oct6100ChannelModifyDef(modify);
++ modify->ulEchoOperationMode = mode;
++ modify->ulChannelHndl = vpm450m->aulEchoChanHndl[channel];
++ ulResult = Oct6100ChannelModify(vpm450m->pApiInstance, modify);
++ if (ulResult != GENERIC_OK) {
++ printk(KERN_NOTICE "Failed to apply echo can changes on channel %d!\n", channel);
++ } else {
++#ifdef OCTASIC_DEBUG
++ printk(KERN_DEBUG "Echo can on channel %d set to %d\n", channel, mode);
++#endif
++ vpm450m->ecmode[channel] = mode;
++ }
++ kfree(modify);
++}
++
++void vpm450m_setdtmf(struct vpm450m *vpm450m, int channel, int detect, int mute)
++{
++ tOCT6100_CHANNEL_MODIFY *modify;
++ UINT32 ulResult;
++
++ modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_KERNEL);
++ if (!modify) {
++ printk(KERN_NOTICE "opvxd115: Unable to allocate memory for setdtmf!\n");
++ return;
++ }
++ Oct6100ChannelModifyDef(modify);
++ modify->ulChannelHndl = vpm450m->aulEchoChanHndl[channel];
++ if (mute) {
++ vpm450m->chanflags[channel] |= FLAG_MUTE;
++ modify->VqeConfig.fDtmfToneRemoval = TRUE;
++ } else {
++ vpm450m->chanflags[channel] &= ~FLAG_MUTE;
++ modify->VqeConfig.fDtmfToneRemoval = FALSE;
++ }
++ if (detect)
++ vpm450m->chanflags[channel] |= FLAG_DTMF;
++ else
++ vpm450m->chanflags[channel] &= ~FLAG_DTMF;
++ if (vpm450m->chanflags[channel] & (FLAG_DTMF|FLAG_MUTE)) {
++ if (!(vpm450m->chanflags[channel] & FLAG_ECHO)) {
++ vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
++ vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_FREEZE);
++ }
++ } else {
++ if (!(vpm450m->chanflags[channel] & FLAG_ECHO))
++ vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_DIGITAL);
++ }
++
++ ulResult = Oct6100ChannelModify(vpm450m->pApiInstance, modify);
++ if (ulResult != GENERIC_OK) {
++ printk(KERN_NOTICE "Failed to apply dtmf mute changes on channel %d!\n", channel);
++ }
++/* printk(KERN_DEBUG "VPM450m: Setting DTMF on channel %d: %s / %s\n", channel, (detect ? "DETECT" : "NO DETECT"), (mute ? "MUTE" : "NO MUTE")); */
++ kfree(modify);
++}
++
++void vpm450m_setec(struct vpm450m *vpm450m, int channel, int eclen)
++{
++ if (eclen) {
++ vpm450m->chanflags[channel] |= FLAG_ECHO;
++ vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
++ vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_NORMAL);
++ } else {
++ vpm450m->chanflags[channel] &= ~FLAG_ECHO;
++ if (vpm450m->chanflags[channel] & (FLAG_DTMF | FLAG_MUTE)) {
++ vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
++ vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_FREEZE);
++ } else
++ vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_DIGITAL);
++ }
++/* printk(KERN_DEBUG "VPM450m: Setting EC on channel %d to %d\n", channel, eclen); */
++}
++
++int vpm450m_checkirq(struct vpm450m *vpm450m)
++{
++ tOCT6100_INTERRUPT_FLAGS InterruptFlags;
++
++ Oct6100InterruptServiceRoutineDef(&InterruptFlags);
++ Oct6100InterruptServiceRoutine(vpm450m->pApiInstance, &InterruptFlags);
++
++ return InterruptFlags.fToneEventsPending ? 1 : 0;
++}
++
++int vpm450m_getdtmf(struct vpm450m *vpm450m, int *channel, int *tone, int *start)
++{
++ tOCT6100_TONE_EVENT tonefound;
++ tOCT6100_EVENT_GET_TONE tonesearch;
++ UINT32 ulResult;
++
++ Oct6100EventGetToneDef(&tonesearch);
++ tonesearch.pToneEvent = &tonefound;
++ tonesearch.ulMaxToneEvent = 1;
++ ulResult = Oct6100EventGetTone(vpm450m->pApiInstance, &tonesearch);
++ if (tonesearch.ulNumValidToneEvent) {
++ if (channel)
++ *channel = tonefound.ulUserChanId;
++ if (tone) {
++ switch(tonefound.ulToneDetected) {
++ case SOUT_DTMF_1:
++ *tone = '1';
++ break;
++ case SOUT_DTMF_2:
++ *tone = '2';
++ break;
++ case SOUT_DTMF_3:
++ *tone = '3';
++ break;
++ case SOUT_DTMF_A:
++ *tone = 'A';
++ break;
++ case SOUT_DTMF_4:
++ *tone = '4';
++ break;
++ case SOUT_DTMF_5:
++ *tone = '5';
++ break;
++ case SOUT_DTMF_6:
++ *tone = '6';
++ break;
++ case SOUT_DTMF_B:
++ *tone = 'B';
++ break;
++ case SOUT_DTMF_7:
++ *tone = '7';
++ break;
++ case SOUT_DTMF_8:
++ *tone = '8';
++ break;
++ case SOUT_DTMF_9:
++ *tone = '9';
++ break;
++ case SOUT_DTMF_C:
++ *tone = 'C';
++ break;
++ case SOUT_DTMF_STAR:
++ *tone = '*';
++ break;
++ case SOUT_DTMF_0:
++ *tone = '0';
++ break;
++ case SOUT_DTMF_POUND:
++ *tone = '#';
++ break;
++ case SOUT_DTMF_D:
++ *tone = 'D';
++ break;
++ case SOUT_G168_1100GB_ON:
++ *tone = 'f';
++ break;
++ default:
++#ifdef OCTASIC_DEBUG
++ printk(KERN_DEBUG "Unknown tone value %08x\n", tonefound.ulToneDetected);
++#endif
++ *tone = 'u';
++ break;
++ }
++ }
++ if (start)
++ *start = (tonefound.ulEventType == cOCT6100_TONE_PRESENT);
++ return 1;
++ }
++ return 0;
++}
++
++unsigned int get_vpm450m_capacity(void *wc)
++{
++ UINT32 ulResult;
++
++ tOCT6100_API_GET_CAPACITY_PINS CapacityPins;
++
++ Oct6100ApiGetCapacityPinsDef(&CapacityPins);
++ CapacityPins.pProcessContext = wc;
++ CapacityPins.ulMemoryType = cOCT6100_MEM_TYPE_DDR;
++ CapacityPins.fEnableMemClkOut = TRUE;
++ CapacityPins.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
++
++ ulResult = Oct6100ApiGetCapacityPins(&CapacityPins);
++ if (ulResult != cOCT6100_ERR_OK) {
++ printk(KERN_DEBUG "Failed to get chip capacity, code %08x!\n", ulResult);
++ return 0;
++ }
++
++ return CapacityPins.ulCapacityValue;
++}
++
++struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware)
++{
++ tOCT6100_CHIP_OPEN *ChipOpen;
++ tOCT6100_GET_INSTANCE_SIZE InstanceSize;
++ tOCT6100_CHANNEL_OPEN *ChannelOpen;
++ UINT32 ulResult;
++ struct vpm450m *vpm450m;
++ int x,y,law;
++#ifdef CONFIG_4KSTACKS
++ unsigned long flags;
++#endif
++
++ if (!(vpm450m = kmalloc(sizeof(struct vpm450m), GFP_KERNEL)))
++ return NULL;
++
++ memset(vpm450m, 0, sizeof(struct vpm450m));
++
++ if (!(ChipOpen = kmalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL))) {
++ kfree(vpm450m);
++ return NULL;
++ }
++
++ memset(ChipOpen, 0, sizeof(tOCT6100_CHIP_OPEN));
++
++ if (!(ChannelOpen = kmalloc(sizeof(tOCT6100_CHANNEL_OPEN), GFP_KERNEL))) {
++ kfree(vpm450m);
++ kfree(ChipOpen);
++ return NULL;
++ }
++
++ memset(ChannelOpen, 0, sizeof(tOCT6100_CHANNEL_OPEN));
++
++ for (x=0;x<128;x++)
++ vpm450m->ecmode[x] = -1;
++
++ vpm450m->numchans = numspans * 32;
++ printk(KERN_INFO "VPM450: echo cancellation for %d channels\n", vpm450m->numchans);
++
++ Oct6100ChipOpenDef(ChipOpen);
++
++ /* Setup Chip Open Parameters */
++ ChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ;
++ Oct6100GetInstanceSizeDef(&InstanceSize);
++
++ ChipOpen->pProcessContext = wc;
++
++ ChipOpen->pbyImageFile = firmware->data;
++ ChipOpen->ulImageSize = firmware->size;
++ ChipOpen->fEnableMemClkOut = TRUE;
++ ChipOpen->ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
++ ChipOpen->ulMaxChannels = vpm450m->numchans;
++ ChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR;
++ ChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB;
++ ChipOpen->ulNumMemoryChips = 1;
++ ChipOpen->ulMaxTdmStreams = 4;
++ ChipOpen->aulTdmStreamFreqs[0] = cOCT6100_TDM_STREAM_FREQ_8MHZ;
++ ChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE;
++#if 0
++ ChipOpen->fEnableAcousticEcho = TRUE;
++#endif
++
++ ulResult = Oct6100GetInstanceSize(ChipOpen, &InstanceSize);
++ if (ulResult != cOCT6100_ERR_OK) {
++ printk(KERN_NOTICE "Failed to get instance size, code %08x!\n", ulResult);
++ kfree(vpm450m);
++ kfree(ChipOpen);
++ kfree(ChannelOpen);
++ return NULL;
++ }
++
++
++ vpm450m->pApiInstance = vmalloc(InstanceSize.ulApiInstanceSize);
++ if (!vpm450m->pApiInstance) {
++ printk(KERN_NOTICE "Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
++ kfree(vpm450m);
++ kfree(ChipOpen);
++ kfree(ChannelOpen);
++ return NULL;
++ }
++
++ /* I don't know what to curse more in this comment, the problems caused by
++ * the 4K kernel stack limit change or the octasic API for being so darn
++ * stack unfriendly. Stupid, stupid, stupid. So we disable IRQs so we
++ * don't run the risk of overflowing the stack while we initialize the
++ * octasic. */
++#ifdef CONFIG_4KSTACKS
++ local_irq_save(flags);
++#endif
++ ulResult = Oct6100ChipOpen(vpm450m->pApiInstance, ChipOpen);
++ if (ulResult != cOCT6100_ERR_OK) {
++ printk(KERN_NOTICE "Failed to open chip, code %08x!\n", ulResult);
++#ifdef CONFIG_4KSTACKS
++ local_irq_restore(flags);
++#endif
++ kfree(vpm450m);
++ kfree(ChipOpen);
++ kfree(ChannelOpen);
++ return NULL;
++ }
++ for (x=0;x<128;x++) {
++ if ((x & 0x03) < numspans) {
++ /* span timeslots are interleaved 12341234...
++ * therefore, the lower 2 bits tell us which span this
++ * timeslot/channel
++ */
++ if (isalaw[x & 0x03])
++ law = cOCT6100_PCM_A_LAW;
++ else
++ law = cOCT6100_PCM_U_LAW;
++ Oct6100ChannelOpenDef(ChannelOpen);
++ ChannelOpen->pulChannelHndl = &vpm450m->aulEchoChanHndl[x];
++ ChannelOpen->ulUserChanId = x;
++ ChannelOpen->TdmConfig.ulRinPcmLaw = law;
++ ChannelOpen->TdmConfig.ulRinStream = 0;
++ ChannelOpen->TdmConfig.ulRinTimeslot = x;
++ ChannelOpen->TdmConfig.ulSinPcmLaw = law;
++ ChannelOpen->TdmConfig.ulSinStream = 1;
++ ChannelOpen->TdmConfig.ulSinTimeslot = x;
++ ChannelOpen->TdmConfig.ulSoutPcmLaw = law;
++ ChannelOpen->TdmConfig.ulSoutStream = 2;
++ ChannelOpen->TdmConfig.ulSoutTimeslot = x;
++ ChannelOpen->TdmConfig.ulRoutPcmLaw = law;
++ ChannelOpen->TdmConfig.ulRoutStream = 3;
++ ChannelOpen->TdmConfig.ulRoutTimeslot = x;
++ ChannelOpen->VqeConfig.fEnableNlp = TRUE;
++ ChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE;
++ ChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE;
++
++ ChannelOpen->fEnableToneDisabler = TRUE;
++ ChannelOpen->ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_DIGITAL;
++
++ ulResult = Oct6100ChannelOpen(vpm450m->pApiInstance, ChannelOpen);
++ if (ulResult != GENERIC_OK) {
++ printk(KERN_NOTICE "Failed to open channel %d!\n", x);
++ }
++ for (y=0;y<sizeof(tones) / sizeof(tones[0]); y++) {
++ tOCT6100_TONE_DETECTION_ENABLE enable;
++ Oct6100ToneDetectionEnableDef(&enable);
++ enable.ulChannelHndl = vpm450m->aulEchoChanHndl[x];
++ enable.ulToneNumber = tones[y];
++ if (Oct6100ToneDetectionEnable(vpm450m->pApiInstance, &enable) != GENERIC_OK)
++ printk(KERN_NOTICE "Failed to enable tone detection on channel %d for tone %d!\n", x, y);
++ }
++ }
++ }
++
++#ifdef CONFIG_4KSTACKS
++ local_irq_restore(flags);
++#endif
++ kfree(ChipOpen);
++ kfree(ChannelOpen);
++ return vpm450m;
++}
++
++void release_vpm450m(struct vpm450m *vpm450m)
++{
++ UINT32 ulResult;
++ tOCT6100_CHIP_CLOSE ChipClose;
++
++ Oct6100ChipCloseDef(&ChipClose);
++ ulResult = Oct6100ChipClose(vpm450m->pApiInstance, &ChipClose);
++ if (ulResult != cOCT6100_ERR_OK) {
++ printk(KERN_NOTICE "Failed to close chip, code %08x!\n", ulResult);
++ }
++ vfree(vpm450m->pApiInstance);
++ kfree(vpm450m);
++}
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/opvxd115/vpm450m.h dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/vpm450m.h
+--- dahdi-linux-2.7.0/drivers/dahdi/opvxd115/vpm450m.h 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/opvxd115/vpm450m.h 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2005-2006 Digium, Inc.
++ *
++ * Mark Spencer <markster@digium.com>
++ *
++ * All Rights Reserved
++ *
++ */
++
++/*
++ * See http://www.asterisk.org for more information about
++ * the Asterisk project. Please do not directly contact
++ * any of the maintainers of this project for assistance;
++ * the project provides a web site, mailing lists and IRC
++ * channels for your use.
++ *
++ * This program is free software, distributed under the terms of
++ * the GNU General Public License Version 2 as published by the
++ * Free Software Foundation. See the LICENSE file included with
++ * this program for more details.
++ */
++
++#ifndef _VPM450M_H
++#define _VPM450M_H
++
++#include <linux/firmware.h>
++
++struct vpm450m;
++
++/* From driver */
++unsigned int oct_get_reg(void *data, unsigned int reg);
++void oct_set_reg(void *data, unsigned int reg, unsigned int val);
++
++/* From vpm450m */
++struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware);
++unsigned int get_vpm450m_capacity(void *wc);
++void vpm450m_setec(struct vpm450m *instance, int channel, int eclen);
++void vpm450m_setdtmf(struct vpm450m *instance, int channel, int dtmfdetect, int dtmfmute);
++int vpm450m_checkirq(struct vpm450m *vpm450m);
++int vpm450m_getdtmf(struct vpm450m *vpm450m, int *channel, int *tone, int *start);
++void release_vpm450m(struct vpm450m *instance);
++
++#endif
+diff -uNr dahdi-linux-2.7.0/drivers/dahdi/wcopenpci.c dahdi-extra-dahdi-linux/drivers/dahdi/wcopenpci.c
+--- dahdi-linux-2.7.0/drivers/dahdi/wcopenpci.c 1970-01-01 01:00:00.000000000 +0100
++++ dahdi-extra-dahdi-linux/drivers/dahdi/wcopenpci.c 2013-06-04 15:18:43.000000000 +0100
+@@ -0,0 +1,1792 @@
++/*
++ * Voicetronix OpenPCI Interface Driver for Zapata Telephony interface
++ *
++ * Written by Mark Spencer <markster@linux-support.net>
++ * Matthew Fredrickson <creslin@linux-support.net>
++ * Ben Kramer <ben@voicetronix.com.au>
++ * Ron Lee <ron@voicetronix.com.au>
++ *
++ * Copyright (C) 2001, Linux Support Services, Inc.
++ * Copyright (C) 2005 - 2007, Voicetronix
++ *
++ * All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ */
++
++/* Conditional debug options */
++#define VERBOSE_TIMING 0
++
++/* Driver constants */
++#define DRIVER_DESCRIPTION "Voicetronix OpenPCI DAHDI driver"
++#define DRIVER_AUTHOR "Mark Spencer <markster@digium.com> "\
++ "Voicetronix <support@voicetronix.com.au>"
++
++#define NAME "wcopenpci"
++#define MAX_PORTS 8 /* Maximum number of ports on each carrier */
++#define MAX_CARDS 8 /* Maximum number of carriers per host */
++
++#define DEFAULT_COUNTRY "AUSTRALIA"
++
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++
++#include <dahdi/kernel.h>
++#include <dahdi/version.h>
++#include "proslic.h"
++#include <dahdi/wctdm_user.h>
++#include <linux/interrupt.h>
++#include <linux/mutex.h>
++
++#include "fxo_modes.h"
++
++#ifndef IRQF_DISABLED
++#ifdef SA_INTERRUPT
++#define IRQF_DISABLED SA_INTERRUPT
++#else
++#define IRQF_DISABLED 0x0
++#endif
++#endif
++
++static struct ps_country_reg {
++ const char *country;
++ unsigned short value;
++} ps_country_regs[] = {
++ {"ARGENTINA", 0x8},
++ {"AUSTRALIA", 0xD},
++ {"AUSTRIA", 0xD},
++ {"BAHRAIN", 0xC},
++ {"BELGIUM", 0xC},
++ {"BRAZIL", 0x8},
++ {"BULGARIA", 0xD},
++ {"CANADA", 0x8},
++ {"CHILE", 0x8},
++ {"CHINA", 0xC},
++ {"COLOMBIA", 0x8},
++ {"CROATIA", 0xC},
++ {"CYPRUS", 0xC},
++ {"CZECH", 0xC},
++ {"DENMARK", 0xC},
++ {"ECUADOR", 0x8},
++ {"EGYPT", 0x8},
++ {"ELSALVADOR", 0x8},
++ {"FINLAND", 0xC},
++ {"FRANCE", 0xC},
++ {"GERMANY", 0xD},
++ {"GREECE", 0xC},
++ {"GUAM", 0x8},
++ {"HONGKONG", 0x8},
++ {"HUNGARY", 0x8},
++ {"ICELAND", 0xC},
++ {"INDIA", 0xF},
++ {"INDONESIA", 0x8},
++ {"IRELAND", 0xC},
++ {"ISRAEL", 0xC},
++ {"ITALY", 0xC},
++ {"JAPAN", 0x8},
++ {"JORDAN", 0x8},
++ {"KAZAKHSTAN", 0x8},
++ {"KUWAIT", 0x8},
++ {"LATVIA", 0xC},
++ {"LEBANON", 0xC},
++ {"LUXEMBOURG", 0xC},
++ {"MACAO", 0x8},
++ {"MALAYSIA", 0x8},
++ {"MALTA", 0xC},
++ {"MEXICO", 0x8},
++ {"MOROCCO", 0xC},
++ {"NETHERLANDS", 0xC},
++ {"NEWZEALAND", 0xF},
++ {"NIGERIA", 0xC},
++ {"NORWAY", 0xC},
++ {"OMAN", 0x8},
++ {"PAKISTAN", 0x8},
++ {"PERU", 0x8},
++ {"PHILIPPINES", 0x8},
++ {"POLAND", 0x8},
++ {"PORTUGAL", 0xC},
++ {"ROMANIA", 0x8},
++ {"RUSSIA", 0x8},
++ {"SAUDIARABIA", 0x8},
++ {"SINGAPORE", 0x8},
++ {"SLOVAKIA", 0xE},
++ {"SLOVENIA", 0xE},
++ {"SOUTHAFRICA", 0xE},
++ {"SOUTHKOREA", 0x8},
++ {"SPAIN", 0xC},
++ {"SWEDEN", 0xC},
++ {"SWITZERLAND", 0xC},
++ {"SYRIA", 0x8},
++ {"TAIWAN", 0x8},
++ {"THAILAND", 0x8},
++ {"UAE", 0x8},
++ {"UK", 0xC},
++ {"USA", 0x8},
++ {"YEMEN", 0x8}
++};
++
++#define INOUT 2
++
++/* Allocate enough memory for two zt chunks, receive and transmit. Each
++ * sample uses 32 bits. Allocate an extra set just for control too */
++#define VT_PCIDMA_BLOCKSIZE (DAHDI_MAX_CHUNKSIZE * INOUT * MAX_PORTS * 2 * 2)
++#define VT_PCIDMA_MIDDLE (DAHDI_MAX_CHUNKSIZE * MAX_PORTS - 4)
++#define VT_PCIDMA_END (DAHDI_MAX_CHUNKSIZE * MAX_PORTS * 2 - 4)
++
++#define ID_DATA_MAXSIZE 30
++
++#define NUM_CAL_REGS 12
++#define NUM_FXO_REGS 60
++
++#define TREG(addr) (wc->ioaddr + addr)
++
++#define TJ_CNTL TREG(0x00)
++#define TJ_OPER TREG(0x01)
++#define TJ_AUXC TREG(0x02)
++#define TJ_AUXD TREG(0x03)
++#define TJ_MASK0 TREG(0x04)
++#define TJ_MASK1 TREG(0x05)
++#define TJ_INTSTAT TREG(0x06)
++#define TJ_AUXR TREG(0x07)
++
++#define TJ_DMAWS TREG(0x08)
++#define TJ_DMAWI TREG(0x0c)
++#define TJ_DMAWE TREG(0x10)
++#define TJ_DMAWC TREG(0x14)
++#define TJ_DMARS TREG(0x18)
++#define TJ_DMARI TREG(0x1c)
++#define TJ_DMARE TREG(0x20)
++#define TJ_DMARC TREG(0x24)
++
++#define TJ_AUXINTPOL TREG(0x2A)
++
++#define TJ_AUXFUNC TREG(0x2b)
++#define TJ_SFDELAY TREG(0x2c)
++#define TJ_SERCTL TREG(0x2d)
++#define TJ_SFLC TREG(0x2e)
++#define TJ_FSCDELAY TREG(0x2f)
++
++#define TJ_REGBASE TREG(0xc0)
++
++#define PIB(addr) (TJ_REGBASE + addr * 4)
++
++#define HTXF_READY (inb(PIB(0)) & 0x10)
++#define HRXF_READY (inb(PIB(0)) & 0x20)
++
++
++#define VT_PORT_EMPTY 0
++#define VT_PORT_VDAA 1 /* Voice DAA - FXO */
++#define VT_PORT_PROSLIC 2 /* ProSLIC - FXS */
++
++#define VBAT 0xC7
++
++#define HKMODE_FWDACT 1
++#define HKMODE_FWDONACT 2
++#define HKMODE_RINGING 4
++
++#define HOOK_ONHOOK 0
++#define HOOK_OFFHOOK 1
++
++#define DSP_CODEC_RING 12 /* RING rising edge detected */
++#define DSP_CODEC_HKOFF 22 /* station port off hook */
++#define DSP_CODEC_HKON 23 /* station port on hook */
++#define DSP_RING_OFF 24 /* RING falling edge detected */
++#define DSP_DROP 25
++
++#define DSP_CODEC_FLASH 26 /* station port hook flash */
++
++#define DSP_LOOP_OFFHOOK 38 /* Loop Off hook from OpenPCI */
++#define DSP_LOOP_ONHOOK 39 /* Loop On hook from OpenPCI */
++#define DSP_LOOP_POLARITY 40 /* Loop Polarity from OpenPCI */
++#define DSP_LOOP_NOBATT 41
++
++#define DSP_PROSLIC_SANITY 50 /* Sanity alert from a ProSLIC port */
++#define DSP_PROSLIC_PWR_ALARM 51 /* Power Alarm from a ProSLIC port */
++#define DSP_VDAA_ISO_FRAME_E 52 /* ISO-cap frame sync lost on VDAA port*/
++
++#if VERBOSE_TIMING
++ #define REPORT_WAIT(n,x) \
++ cardinfo(card->cardnum, #n " wait at %d, " #x " = %d", __LINE__, x )
++#else
++ #define REPORT_WAIT(n,x)
++#endif
++
++#define BUSY_WAIT(countvar,cond,delay,iter,failret) \
++ countvar = 0; \
++ while(cond){ \
++ udelay(delay); \
++ if (++countvar > iter){ \
++ cardcrit(wc->boardnum, "busy wait FAILED at %d", __LINE__); \
++ return failret; \
++ } \
++ } \
++ REPORT_WAIT(busy,i)
++
++#define LOCKED_WAIT(countvar,cond,delay,iter,failret) \
++ countvar = 0; \
++ while(cond){ \
++ udelay(delay); \
++ if (++countvar > iter){ \
++ dbginfo(wc->boardnum,"busy wait failed at %d",__LINE__); \
++ spin_unlock_irqrestore(&wc->lock, flags); \
++ return failret; \
++ } \
++ } \
++ REPORT_WAIT(locked,i)
++
++#define HTXF_WAIT() BUSY_WAIT(i,HTXF_READY,5,500,RET_FAIL)
++#define HRXF_WAIT() BUSY_WAIT(i,!HRXF_READY,5,70000,RET_FAIL)
++#define HTXF_WAIT_RET(failret) BUSY_WAIT(i,HTXF_READY,5,500,failret)
++#define HRXF_WAIT_RET(failret) BUSY_WAIT(i,!HRXF_READY,5,1000,failret)
++
++#define HTXF_WAIT_LOCKED() LOCKED_WAIT(i,HTXF_READY,5,500,RET_FAIL)
++#define HRXF_WAIT_LOCKED() LOCKED_WAIT(i,!HRXF_READY,5,1000,RET_FAIL)
++#define HTXF_WAIT_LOCKED_RET(failret) LOCKED_WAIT(i,HTXF_READY,5,500,failret)
++#define HRXF_WAIT_LOCKED_RET(failret) LOCKED_WAIT(i,!HRXF_READY,5,1000,failret)
++
++
++static struct openpci {
++ struct pci_dev *dev;
++ char *variety;
++ int boardnum;
++ int portcount;
++ int porttype[MAX_PORTS];
++
++ int firmware;
++ char serial[ID_DATA_MAXSIZE];
++
++ spinlock_t lock;
++
++ //XXX Replace these with proper try_module_get locking in the dahdi driver.
++ //int usecount; //XXX
++ //int dead; //XXX
++ union {
++ struct {
++ int offhook;
++ } fxo;
++ struct {
++ int ohttimer;
++ int idletxhookstate; /* IDLE changing hook state */
++ int lasttxhook;
++ } fxs;
++ } mod[MAX_PORTS];
++
++ unsigned long ioaddr;
++ dma_addr_t readdma;
++ dma_addr_t writedma;
++ volatile unsigned int *writechunk; /* Double-word aligned write memory */
++ volatile unsigned int *readchunk; /* Double-word align